什么是“if(self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])”

时间:2011-03-11 04:29:33

标签: ios objective-c

想知道以下代码中if (self = [super ...的含义是什么?它试图防范什么情况?

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
        // STUFF CONFIGURED HERE
    }
    return self;
}

采取from here

3 个答案:

答案 0 :(得分:5)

它正在防止超级实现返回nil。如果超类决定它无法初始化对象,它可能会释放它并返回nil,如果你试图进行任何初始化,那么会导致程序崩溃,因为你试图取消引用nil指针。

答案 1 :(得分:1)

如果超类中的函数失败并返回nil,那么“// STUFF CONFIGURED HERE”代码将不会执行,函数将返回nil。

这可能是你想要的行为,因为你的“// STUFF CONFIGURED HERE”代码可能依赖于超类函数来正常工作。

答案 2 :(得分:0)

super的初始化程序可以自由返回nil,也可以指向self之外的对象。这看起来很奇怪,但你不必看很远就能找到例子。考虑:

NSString *string1 = @"foo";
NSString *string2 = [[NSString alloc] initWithString:string1];
NSLog(@"\nstring1 is located at:%p \nstring2 is located at:%p", string1, string2);

显然,string1和string2是两个不同的对象,对吧?一个是常量字符串,另一个是在堆上的某处分配。所以看到这段代码的结果有点令人惊讶:

string1 is located at:0x3044 
string2 is located at:0x3044

为什么两个指针都一样?好吧,NSStrings是不可改变的。由于它们无法改变,因此永远不会有两个具有完全相同值的理由。 NSString的-initWithString:方法如下:

-(NSString*)initWithString:(NSString*)string
{
    if ([string isMemberOfClass:[NSString class]] == YES) {
        [self release];
        self = [string retain];
    }
    else {
        // set up new immutable copy of string here
    }
    return self;
}

注意不寻常的'[自我释放]'。一个init方法将返回一个除了被分配的对象以外的对象,这是少数几个向自己发送-release有意义的情况之一。

还有其他情况,初始化程序可能决定返回一个不同的对象,或者nil,这就是为什么始终将super的初始化程序的结果赋给self的重要性。在访问其实例变量之前检查返回的指针是否为nil也很重要,这就是为什么赋值发生在'if'条件内。