Are instance variables set to nil by default in Objective-C?
Asked Answered
P

3

39

I'm sorting out some memory issues with my iPhone app and I've just been thinking about some basics. If I setup an ivar and never end up using it in the lifespan of my object, when I call dealloc on it, will that cause a problem? E.g.

@interface testClass {
    id myobject;
}
@property (nonatomic, retain) id myobject;
@end

@implementation testClass
@synthesize myobject;
- (id)init {
    ...
    // Do I have to set myobject to nil here?
    // So if myobject isn't used the dealloc call to nil
    // will be okay? Or can you release the variable without
    // having set every object to nil that you may may not use 
    ...
}

...

// Somewhere in the code, myobject may be set to
// an instance of an object via self.myobject = [AnObject grabAnObject]
// but the object may be left alone

...

- (void)dealloc {
    [myobject release];
    [super dealloc];
}
@end
Personify answered 23/11, 2009 at 23:25 Comment(4)
Mike Abdullah: I've made that change in my edit.Streptokinase
Ah right, so normal variable's created in a function aren't set to 0/nil when you declare them then? Just instance variables. So is it correct that normal variables will just contain 'garbage' until you explicitly set it to something?Personify
@MichaelWaterfall Local object variables are automatically initialized to nil.Alitaalitha
... when you are using ARC, which you should.Finbar
T
61

Instance variables are initialized to 0 before your initializer runs..

Transude answered 23/11, 2009 at 23:34 Comment(0)
M
11

Yes, ivars are always initialized to 0/nil/NULL/NO/etc.

However, if it helps you understand what's going on, go for it. The performance impact is negligible. You don't need to do it, but it won't cause any problems if you do.

Mazdaism answered 23/11, 2009 at 23:33 Comment(8)
I don't see how wasted, redundant code is good practice. Do you make sure to set all your local variables to the same value several times in a row just to make it really explicit?Transude
No. Setting local variables multiple times would reduce the clarity of the code and increase confusion. Explicitly setting an ivar increases clarity, and a new member of the team less familiar with objc understand more easily what's happening. Code clarity is more important than reducing "wasted" code.Mazdaism
Objective-C developers should be familiar with the zero-initialization of ivars. Due to zeroing init methods can often be omitted completely, which is a good thing. If developers are still learning they shouldn’t learn this concept from code but from a book, instructor, SO or whatever. They would not learn this concept by reading redundant code, anyway.Shoer
This is bad advice. There is absolutely no reason to set your ivars to nil.Grateful
Updated my answer to remove the incorrect assertion that it's 'good practice' to do so.Mazdaism
To beat a dead horse a bit more, to set them to nil actually increases confusion, because when a knowlegable Cocoa programmer sees that, he says to himself, "Now, why is that being set to nil? Perhaps the superclass sets it to something, so the author of this class wanted to undo that...now I have to go look"Abrahan
If you have more than one object, and some should be nil and others not, it's worth it to set an object to nil to make clear you knew what you are doing. For example _array1 = nil; _array2 = [NSMutableArray array]; _array3 = [NSMutableArray array]; so nobody thinks you've forgotten array1.Finbar
"Explicitly setting an ivar increases clarity, and a new member of the team less familiar with objc understand more easily what's happening" Uggh. Never code for an audience of people who don't know the basics of the language. Would you also put comments above init method explaining what init does?Colored
H
0

I find that it is good practice to always set those ivars to nil in the init method. That way, you are absolutely sure that your call to release in the destructor can not cause problems.

If it turns out that Objective-C does automatically set them to nil, and for some reason you find yourself with a speed bottleneck that can be improved upon by removing those assignments (highly unlikely), then you can worry about removing them. In the meantime, set them all to nil and sleep easier :)

update: BJ Homer and Chuck have pointed out that the ivars will automatically be set to zero, so now it comes down to a decision on style.

Heptagonal answered 23/11, 2009 at 23:31 Comment(2)
You can be sure either way. Just one way your init method is full of a useless assignments.Transude
The best code is the code you don't have to write. If a language makes guarantees, make use of them. If you start doubting the documentation of the basics of the language (like nilling of ivars) then you're in a real rabbit hole.Colored

© 2022 - 2024 — McMap. All rights reserved.