在Objective-C中,如何处理[[myView alloc] init]返回nil?

时间:2012-04-27 22:27:44

标签: iphone objective-c ios error-handling

似乎在书的代码示例中,始终定义init,以便仔细检查self是否能够存在。

-(id) init {

    self = [super init];
    if (self) {
        // initialize
    }
    return self;
}

但是,返回时,根本没有代码检查对象是否能够存在。但它应该检查,如何处理?如果对象不存在,那是否意味着系统严重缺乏内存,甚至弹出错误信息也是不可能的?

2 个答案:

答案 0 :(得分:4)

  

但是,返回时,根本没有代码检查对象是否能够存在。但是应该检查一下,它是如何处理的?

通常,返回nil时,子类会忽略错误处理。返回nil时,通常会将错误处理留给调用者。正如惯用语-init

中所示
- (id)init {
  self = [super init];
  if (self) {
    // initialize
  }
  return self;
}

同样,如果基地在self中重新分配init,则会重新分配selfself = [super init];)。效果很好。

如果您未能将self分配给super的初始化程序的结果,或者如果您未能检查nil,那么您可能会抓住悬空/取消分配的指针(EXC_BAD_ACCESS),您可能无法正确初始化您的ivars(如果未遇到EXC_BAD_ACCESS,您可以将它们有效地分配到其他区域。)

更详细的两个案例:

无法分配自己

- (id)init {
  [super init];
  if (self) {
    // self was not reassigned. if super returned an object other
    // than self, then our ivar would be freed, reused, or sitting
    // in an autorelease pool, and the returned instance's ivar
    // would not be assigned -- we wouldn't know the address.
    ivar = 1;
  }
  return self;
}

检查无法

- (id)init {
  self = [super init];
  // super returned nil. ivar is an invalid region:
  ivar = 1;
  return self;
}

是的,我已经看到了这两个。


  

如果对象不存在,这是否意味着系统严重缺乏内存,甚至弹出错误信息也是不可能的?

完全没有。许多初始化程序返回nil表示“在此上下文中无法执行”,或者如果存在简单的参数错误。

答案 1 :(得分:3)

  

这是否意味着系统严重缺乏内存

没有。分配内存失败通常会导致+ alloc失败,而不是-init。

实际上,没有参数的init方法失败是非常罕见的。如果你传递了无效的参数,通常init方法可以返回nil,例如NSString的-initWithContentsOfFile:如果它无法加载应该用它初始化的文件路径的内容,则可以返回nil。

如果您意识到init失败的可能性很大,那么您可能需要检查它,否则,您应该继续使用该对象。