Clarification of when to release pointers after highlighting

In my last question ( here ) I had a problem when I was getting EXC_BAD_ACCESS because I was releasing the just allocated variable:

NSMutableArray* s = [[NSMutableArray alloc] init]; stack = s; [s release]; 

should be

 NSMutableArray* s = [[NSMutableArray alloc] init]; stack = s; 

However, the stack is a saved property of my class. It was said like this:

 @interface StateStack () @property (nonatomic, retain) NSMutableArray* stack; @end 

I got the impression that when you assign the "save" variable, it automatically increases the keepCount value of the object. So, you should start by issuing your pointer ( here ).

Why are these two cases different? Thanks!

+2
source share
4 answers

There is no such thing as "save a variable." This property , which means that the setter method saves the new value after the property and frees the old one. But variable assignment is simply assigned. In fact, the reason people usually recommend assigning directly to an instance variable in init , in particular, is because it does not go through the setter, because the installer may have side effects that you don't want in init (when your object is still not fully designed).

Note. Here I am talking about normal memory management rules. This is all different if you use ARC. But I guess you would mention if you were.

+3
source

Because you had to assign a property, not an instance variable. When you assign a property, it will save the variable again, and then you will not have a problem. Here is what your code should look like:

 NSMutableArray* s = [[NSMutableArray alloc] init]; self.stack = s; [s release]; 

Thus, you do not assign this variable, but use a property (this is, in fact, a method). If you did not release in this case, then you will have a memory leak in your code.

When you did stack = s , you assigned directly to the instance variable, and the array was never saved.

+6
source

self.stack and stack are two completely different things. When you use stack , you access the instance variable, not the property. This means that your access methods are not being called, which means that automatic memory management is not used. That is why you should not release s in your example.

If you used self.stack instead, you would use a property. The compiler will handle self.stack = value just like [self setStack:value] , and self.stack same as [self stack] . As accessors are used, memory management will take care of how you defined your property, and you must free the value after it is assigned.

+3
source

Mauricio has the correct answer: remember to assign a property to take advantage of @property. To clarify this point, try using this code:

 @interface StateStack : NSObject { NSArray *_stack; } @property (nonatomic,retain) NSMutableArray *stack; @end @implementation StateStack @synthesize stack=_stack; @end 

Now if you try:

 NSMutableArray* s = [[NSMutableArray alloc] init]; stack = s; [s release]; 

You will receive an error message that will mean that you tried to set ivar and not the property as intended. This discrepancy between the ivar name and the property name is contrary to Apple's recommendations, but it is a great way to help you develop the habit of using property assignment when you intend to do so.

+1
source

All Articles