在Objective-C中分配给self

fbr*_*eto 29 initialization objective-c self

我来自C++世界所以分配的概念this让我不寒而栗:

this = new Object; // Gah!
Run Code Online (Sandbox Code Playgroud)

但是在Objective-C中有一个类似的关键字,self这是完全可以接受的:

self = [super init]; // wait, what?
Run Code Online (Sandbox Code Playgroud)

许多示例Objective-C代码在init例程中使用上述行.我的问题:

1)为什么赋值self有意义(答案如"因为语言允许它"不计算)

2)如果我不在self我的init日常工作中分配会怎样?我是否将我的实例置于某种危险之中?

3)当以下if语句失败时,它意味着什么,我该怎么做才能从中恢复:

- (id) init
{
    self = [super init];

    if (self)
    {
        self.my_foo = 42;
    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ong 33

这是一个经常受到新人挑战的话题:

基本上,它源于这样的想法:超类可能已经超越了指定的初始化程序,以返回与返回的对象不同的对象+alloc.如果您没有将super初始化程序的返回值分配给self,那么您可能正在处理部分初始化的对象(因为super初始化的对象与您正在初始化的对象不同).

总的来说,super返回不同的东西是非常罕见的,但它确实发生在几个案例中.

  • 好答案.另外,谈到Objective-C,我总是相信**@ bbum**... http://stackoverflow.com/questions/1287950/#1289199 (3认同)
  • 您已经做出了错误的假设,即网络上的任何内容都不会发生变化,并且这些链接将永远有用.网络确实发生了变化,一半的链接都被破坏了.在回答问题时,请回答问题.引用东西并用链接获取它们很好,但实际上写出了答案! (2认同)

Chu*_*uck 10

在Objective-C中,初始化程序可以选择在失败时返回nil或返回与调用初始化程序的对象完全不同的对象(例如,NSArray总是这样做).如果未捕获返回值init,则该方法可能正在释放的对象的上下文中执行.

如果你不期望从超类初始化器中获得别的东西,有些人不同意你是否应该完成整个分配到自我的分类,但它通常被认为是良好的防御性编码.

是的,它看起来很奇怪.


Pey*_*loW 6

nil如果初始化失败,init可能会返回.但这并不是您在实现自己的初始化程序时应该为自己分配的主要原因.

之前已经提到过,但需要更加强调:从初始化程序返回的实例可能与您发送的实例不同,实际上它甚至可能不属于同一类!

有些类使用它作为标准,例如所有初始化程序,NSString并且NSArray将始终返回不同类的新实例.初始化器UIColor将经常返回专用类的不同实例.

如果你愿意,你自己可以实现这样的事情:

-(id)initWithName:(NSString*)name;
{
  if ([name isEqualToString:@"Elvis"]) {
    [self release];
    self = [[TheKing alloc] init];
  } else if (self = [super init]){
    self.name = name;
  }
  return self;
}
Run Code Online (Sandbox Code Playgroud)

这允许您将某些特殊情况的实现分解为单独的类,而不需要API的客户端关心甚至了解它.