Search code examples
iosmemory-managementpropertiesretain

Confusing about memory management on IOS


There's a little bit uncommon situation in my app, that is,

I have to reload some retain properties everytime when the view is going to appear,

the code looks like this:

// .h
@property (nonatomic, retain) NSArray *myData;
// .m
@synthesize myData;
- (void)viewWillAppear:(BOOL)animated {
    ... // get FetchRequest and so on
    self.myData = [self.context executeFetchRequest:request error:&error]; // Line 1
[super viewWillAppear:animated];
}
- (void)viewDidUnload {
    self.myData = nil;
    [super viewDidUnload];
}
- (void)dealloc {
    [myData release];  // Line 2
    [super dealloc];
}

there are several points:

1st. as you see, the property "myData" is retain, so I think every I set some object for it, it would automatically retain that object?

2nd. I have to reload "myData" everytime the view will appear, just like the code of Line 1 above.

3rd. Since it is a retain property, I have to release it myself correctly.

Now, question is, do I correctly managed the memory without any leaking of "myData" using the codes above?

If the view would appear many times before it is dealloc, (like push in a further view in a UINavigationController and pop out for several times),

then myData would retain some object more than once, but I only release it in the dealloc for 1 once in Line 2, so is that ok?

But if I add this method the to viewController,which I think is more safe for avoiding memory leaks:

- (void)viewWillDisappear:(BOOL)animated {
    self.myData = nil;
    [myData release];
[super viewWillDisappear:animated];
}
- (void)dealloc {
 //   [myData release];  // don't release it here.
    [super dealloc];
}

my app would crash after one or two times I push in and pop out the view,

So which one is really wrong?

Thanks a lot!


Solution

  • You are not only releasing it in Line 2, it will be also released in Line 1 when replaced as well as in viewDidUnload, so your code on top is just fine. The key is that

    self.myData = anything;
    

    is expanded to

    [self->myData release];
    self->myData = [anything retain];
    

    so by assigning anything (including nil) you are already calling release implicitly. You could in fact replace Line 2 with self.myData = nil; to have never to call release since you don't have any explicit retain.