简体   繁体   中英

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM