开发者

what's the point of "if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) "

开发者 https://www.devze.com 2023-02-15 23:43 出处:网络
Wondering what the point of if (self = [super ... in the following code is? What scenario is it trying to protect against?

Wondering what the point of if (self = [super ... in the following code is? What scenario is it trying to protect against?

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
    if (开发者_开发知识库self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
        // STUFF CONFIGURED HERE
    }
    return self;
}

Taken from here.


It is protecting against the super implementation returning nil. If the superclass decides that it can't initialize the object, it could release it and return nil, which would then crash the program if you tried to do any initialization because you are trying to dereference a nil pointer.


If the function in the super class fails and returns nil, then the "//STUFF CONFIGURED HERE" code won't execute, and the function will just return a nil.

Which is probably the behavior you want since your "//STUFF CONFIGURED HERE" code probably relies on the super classes function to work without errors.


super's initializer is free to return not just nil, but also a pointer to an object other than self. That seems strange, but you don't have to look very far to find examples. Consider:

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

Obviously, string1 and string2 are two different objects, right? One is a constant string, and the other is alloc'ed somewhere on the heap. So it's a bit surprising to see the result of this code:

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

Why are both pointers the same? Well, NSStrings are immutable. Since they can't change, there's never a reason to have two with the exact same value. NSString's -initWithString: method look like:

-(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;
}

Note the unusual '[self release]'. An init method that's going to return an object other than the one that was alloc'ed is one of the few cases where it makes sense to send -release to self.

There are other cases where an initializer might decide to return a different object, or nil, and that's why it's important to always assign the result of super's initializer to self. It's also important to check that the returned pointer is non-nil before accessing its instance variables, which is why the assignment takes place inside an 'if' condition.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号