More specific, general Objective-C memory management

Everything I've read about objective-c memory management makes it incredibly simple. To paraphrase everyone: "release whatever you select, save or copy." But I think there are a few more specific cases that are not so clear. Below are examples of situations. What's the right procedure for everyone:

SITUATION No. 1:

Foo *foo = [[foo alloc] init];
Foo *fooToo = [[[foo alloc] init] autorelease];

foo = fooToo;

      

does foo need to be freed before assigning it to fooToo?

SITUATION # 2 I seem to have a lot of glitches when I do things like: (.h and .m for convenience).

Foo *foo;
@property (nonatomic, retain) Foo *foo;
@synthesize foo;

-(id)init{
self = [super init];
}

-(void)dealloc{
[super dealloc];
[foo release];
}

      

I am constantly told: "Always release in dealloc what you set the save property". But it will fail if done as I showed.

SITUATION # 3 A similar situation that will also crash: (.h and .m for convenience).

Foo *foo;
@property (nonatomic, retain) Foo *foo;
@synthesize foo;

-(id)init{
self = [super init];
self.foo = nil;
}

-(void)dealloc{
[super dealloc];
[foo release];
}

      

for some reason, when my code does this before dealloc, foo is not == nil.

SITUATION # 4 Finally, just a question of what general thinking process people use when choosing between

 self.foo = bar;

      

and

 foo = bar;

      

when is foo declared the same as in the above cases? Is self.foo

just another way of coding:

foo = [bar retain]

;

+2


source to share


2 answers


Situation number 1:

Yes, you need to free foo

it before you lose the link to it. Given that you singled it out, you are responsible for freeing it. If you reassigned foo

before its release, you will no longer be able to release it!

Situation number 2:

Correct implementation dealloc

:

- (void)dealloc {
    [foo release];
    [super dealloc];
}

      

The method dealloc

must call the super method dealloc

, not the method release

. Also, you need to release the fields first before calling[super dealloc]



Situation # 3: Same as Situation # 2.

Situation number 4:

I always prefer to use self.foo = bar

as it does the following steps when needed:

  • liberation foo

  • preservation bar

  • appropriation foo

    bar

Assigns foo = bar

and foo = [bar retain]

does not release the previous object foo

.

+6


source


Wait. Stop. Msaeed's answer is correct, in turn, but fails to highlight the real problem.

Either you don't think like a computer, or you use too much magic for every line of code.

Please don't take this as an insult to make a very light mistake and do what every programmer does when new in the environment (I've made some really fantastic magic assumptions since Objective-C in 1989).

Review the situation.

SITUATION # 1: ... delete unnecessary code ...

foo = fooToo;

This is a simple assignment. Regardless of foo

what was contained before, the object reference in your case will now be overwritten by the value fooToo

. There is no magic. There is no additional execution of the method or lines of code.

If foo

contains a reference to a saved pior object to that line of code. The link will be overwritten. If you need release

foo

to do so before rewriting the link, but it's orthogonal to the assignment.

SITUATION # 2: ... delete unnecessary code ...

-(void)dealloc{ [super dealloc]; [foo release]; }

Computer playback; you ask super dealloc and then assume the instance variable is valid after the super has been deallocated. Bad news. Boom.



There is no magic here. foo

is a reference via self of an instance variable. -dealloc

destroys self and therefore foo

has no effect anymore.

(I believe the static analyzer will catch this. If not, it should.)

SITUATION No. 3:

See # 2. This is the same problem. You are accessing an instance variable of an instance that is no longer valid.

SITUATION No. 4:

self.foo = bar;

The same as:

`[self setFoo: bar];

(Banning any setter = shenanigans)

So the key difference is what the implementation - handwritten or @synthesized - of -setFoo: does. In your case, this is retain

bar. What is different from foo = bar;

what is not saved; it's just the destination of the link to bar

.

I highly recommend that you review the introductory Objective-C documentation. This will help. However, I also encourage you to step back and really think through what exactly each line of code does in the situations above. There is no magic and the actual behavior is very simple.

+4


source







All Articles