views:

192

answers:

2

This is probably a silly question but I have been thinking it over for a while with no obvious answer.

I have a small app that I have been working on and am having a problem with my NSMutableArray instance variable. It was always (null) until I added an [[NSMutableArray alloc]init] to the viewDidLoad.

I am pretty new to the Objective C world so I am trying to get an understanding of this issue. I was under the impression that with I instantiated my class the instance variables were all alloc'd. When I add items to the array without the alloc/init it remains (null) with a retain count of 0.

The array in question was declared as a (retain) property.

I can add code if this isn't clear.

+5  A: 

Any instance variables that are objects are actually just pointers that are initialized to nil (0). That is why the item isn't retained and added to the array, since messages to nil objects return nil/0.

You need to alloc and init the object in your class's init, and then release it in the dealloc.

Andy
So the pointer is created but no memory is actually allocated on instantiation? If I declare my ivar as a (retain) property would the generated setter alloc the memory?
Eric
@Eric: It's meaningless for a setter to alloc memory for the variable. You need to pass in a valid instance to the setter, in which case memory has already been allocated. There's no way for the language to magically know how you want your ivars set up just because you declared them to be of a specific type.
Chuck
@Chuck: I understand now. Thanks very much for your help!
Eric
+2  A: 

The retain/assign/copy qualifiers on the property declaration are about how the memory for the property value is managed in the getters and setters that the compiler synthesizes for you. (The documentation discusses them in detail, and gives example code for each kind.)

That's completely orthogonal to whether your instance variables are initialized for you or not. Declaring an ivar is just reserving storage for the value; for Objective-C classes, that's a pointer to an instance. The runtime will initialize those ivars to zero for you, but you're still responsible for creating the objects you want to store there. (The same is true in similar languages like Java or C#: declaring an Array instance variable just gives you space for a reference, it doesn't create the array for you.)

Sixten Otto
When you say that declaring the ivar reserves space for the value, are you referring to the pointer value and not the actual memory used for the object?
Eric
Correct. The ivar is just a pointer. The runtime will set it to `nil` when your instance is `alloc`ed, and it'll never be anything different unless you point it at something.
Sixten Otto