代码之家  ›  专栏  ›  技术社区  ›  Lothar

从[[class alloc]init]返回nil是否被认为是良好的做法?

  •  2
  • Lothar  · 技术社区  · 15 年前

    在宾语C中它是一个常见的习语吗?

    我只在[[nsimage alloc]initWithContentsOfFile:str]上看到过这个用法,它总是让我觉得内存泄漏,因为我调用了alloc,并且咒语是: “调用alloc,您必须调用release”——除非它是您不需要的情况之一。

    3 回复  |  直到 13 年前
        1
  •  6
  •   Barry Wark    15 年前

    表示初始化对象时出错是一个常见的习惯用法。您是正确的,但是必须释放分配的实例。所以模式是

    - (id)init
    {
      self = [super init];
      if(self != nil) {
        //... do init
        if(errorInInit) {
          [self release];
          return nil;
        }
      }
    
      return self;
    }
    
        2
  •  0
  •   bfavaretto    13 年前

    using alloc and init 有关init方法的更多问题和答案。

    也接受参数的init方法(例如: initWithXxx:(Xxx*)x NSString initWithBytes: 可以返回 nil 从未打过电话 [super init] 如果(例如)它不喜欢它收到的参数。init方法必须像任何方法一样管理内存。只是init有一些不寻常的行为 self 或者返回它选择的其他对象。一般来说,这个要求不高。

        3
  •  0
  •   Community Mohan Dere    8 年前

    关于这个主题的两个后续问题,我还没有看到确切的答案——现在在它自己的问题中重复, Followup to returning nil from a [[class alloc] init]

    1:如果一个init在调用super之前有一些先决条件失败,该怎么办?例如,假设在这个initWithStuff中:方法被传递为nil,或者通常没有值传递给initWithValue:是一个绝对失败,我们肯定希望返回nil。

    - (id)initWithStuff:(Stuff *)inStuff {
      if (!inStuff || ![inStuff hasValidValue])
      {
        // can't proceed to call initWithValue: because we have no value
        // so do what?
        return nil;
      }
      NSInteger value = [inStuff integerValue];
      return [super initWithValue:value];
    }
    

    也许一个更清楚的例子是,如果我们包装的指定初始值设定项方法使用对象指针,并且如果传递了nil,则抛出异常。我们肯定需要将引发异常的init调用短路。

    我的猜测是:以任何可能的方式初始化,然后在返回零之前释放自我。如有必要,调用bare init或任何其他初始值设定项,以在释放自我之前完成将其置于已知状态。

      // can't proceed to call super's initWithValue: because we have no value
      // so do what? do this:
      self = [super init]; // or initWithValue:0
      [self release];
      return nil;
    

    如果没有有效数据,就没有这样的初始值设定项可以工作,我想我们需要构造一些有效的虚拟数据。或者向作者抱怨,直到那时候,只需把零还给作者,就可以忍受泄漏:^)

    2:ARC是如何影响情况的?

    我的猜测是:无论如何都要完成init,然后返回nil。你可能会认为自我设置是多余的,但在某些情况下不是。在任何情况下,它都需要存在才能使编译器警告静音。

      // can't proceed to call super's initWithValue: because we have no value
      // so do what? do this:
      self = [super init]; // finish init so ARC can release it having no strong references
      return nil;