Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I write [anView release], anView = nil; rather than [anView release];?

Somewhere I was reading that - regarding low memory warnings and giving up an non-visible view with all it's subviews (= a whole nib, I think), you should do that:

-(void)dealloc {
    [anView release], anView = nil;
    [someImageView release], someImageView = nil;

    [super dealloc];
}

rather than

-(void)dealloc {
    [anView release];
    [someImageView release];

    [super dealloc];
}

What's the reason for grounding those pointers to nil (= "no object"), after I call release? Let me guess: Some other method could have -retain'ed the view for some reason (anyone any example for when this could happen?), then the didReceiveMemoryWarning thing happens, and you release a whole nib+view that's currently not visible (i.e. in a multiview-app). As soon as the user wants to see that view again, you would quickly load the nib again and then: It loads all views, connects the outlets, and BANG! Your other retain'ed view's are hanging now without any pointer somewhere lonely in the memory brick, causing a fat and deep memory leak until your app crashes.

Right/Wrong?

like image 808
Thanks Avatar asked Apr 30 '09 08:04

Thanks


3 Answers

The principle is more general than UIView. indeed it is more general than Objective-C/Cocoa -release method. It is valid also with C malloc()/free() memory functions.

When you no longer need an object or any memory zone, first you release/free it. Then, to make sure that you won't use it again, you clear the means to access this object or memory zone by assigning a nil to an object or a NULL to a memory pointer.

like image 62
mouviciel Avatar answered Nov 09 '22 00:11

mouviciel


Some other method could have -retain'ed the view for some reason

Unless you're invoking dealloc yourself, it's only called when the retain count becomes zero.

Note that in Objective-C sending a message to a nil "object" is (often) perfectly fine. Doing so will not make your program halt, but the message is simply ignored. However, you cannot send a message to a freed object, which would yield a crash.

So, the following would give you an error:

[anView release];
[anView doSomething];

But, this is in fact ok:

[anView release];
anView = nil;
[anView doSomething];

It's a matter of taste, but for the above, you might in fact prefer to crash your program, rather than wondering why doSomething is not executed...

See also Sending Messages to nil from Apple's Introduction to The Objective-C 2.0 Programming Language.

like image 11
Arjan Avatar answered Nov 09 '22 01:11

Arjan


The -dealloc method is called when the object is freed and no other methods on the object will be executed after. Therefore, setting any instance variable to nil has no effect outside that object.

If you were releasing an object (without using a setter) somewhere else in the class, it would be important to set the instance variable to nil to prevent code elsewhere from sending a message to that address.

like image 4
retainCount Avatar answered Nov 09 '22 00:11

retainCount