开发者

iPhone Memory release issue

I've some doubts regarding dealloc function in iPhone program. Is it required to give [self.object_name release] or [object_name release] is ok?.. I've this strange problem in my dealloc function is like this.

-(void) dealloc {
   [self.listOfDates release];
   [self.listOfDescriptions release];
   [super dealloc];
 }

But program crashes giving EXEC_BAD_ACCESS. Here both objects are NSMutableArray instances allocated with alloc in init function for the class. The same function without self works fine i.e

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

Here is how I declared the property

@property (nonatomic,retain) NSMutableArra开发者_StackOverflow社区y *listOfDates;
@property (nonatomic,retain) NSMutableArray *listOfDescription;

In the implementation file I sysnthesized this and inside the init function I've allocated these variables like this

self.listOfDates = [[NSMutableArray alloc] init];
self.listOfDescription = [[NSMutableArray alloc] init];

So is it required to give self ? What am I missing here?

Issue resolved when I removed mutableCopy function which I had used to copy instance of NSMutableArrays which were passed as argument to the init function as shown below

-(id)initWithDate:(NSMutableArray *)dates andDescription:(NSMutableArray*)descriptions
{
    if(self = [super initWithNibName:@"DateDescriptionControl" bundle:nil])
    {
        self.listOfDates = [[NSMutableArray alloc] init];
        self.listOfDescription = [[NSMutableArray alloc] init];

        self.listOfDates = [dates mutableCopy];
        self.listOfDescription = [description mutableCopy]; 

    }

   return self;
}

After removing the mutableCopy the dealloc is now not throwing EXEC_BAD_ACCESS. So where have I made the mistake I still can't figure out :(


self is not required for releasing in dealloc function.


In dealloc you have two choices:

[foobar release];

or

self.foobar = nil;

The second one is equivalent to writing [self setFoobar:nil] and it is inside the setFoobar: method is where the previous value is being released (assuming the property was defined as using retain or copy). I tend to prefer the first form, where you just send release directly to the object, but either will do.

Writing [self.foobar release] should technically be OK, although if you later call self.foobar = nil the object will be released a second time (and cause EXC_BAD_ACCESS).


self.something means [self something] since the dot means property syntax. What you want is self->something.


yes,

[object release];

should work fine.


The basic problem you are having is caused by this code:

self.listOfDates = [[NSMutableArray alloc] init];

When a property is "retain" and you access it via the setter then the object assigned to it should be in the autorelease pool, like so:

self.listOfDates = [[[NSMutableArray alloc] init] autorelease];

But, this is kind of ugly and the NSMutableArray provides a nice constructor that does this for you automatically:

self.listOfDates = [NSMutableArray array];

Your code is not using ARC, so the object should be in the autorelease pool. If you were using ARC then the rules are a little different.


Best Practice(Non ARC). Within your Interface Declare Varibal like below

NSMutableArray *_listOfDates;
NSMutableArray *_listOfDescription;

And your Setters should be below. (as same as your code)

@property (nonatomic,retain) NSMutableArray *listOfDates;
@property (nonatomic,retain) NSMutableArray *listOfDescription;

In your implementation

@synthesize listOfDates = _listOfDates, listOfDescription = _listOfDescription;

In initialization

-(id)initWithDate:(NSMutableArray *)dates andDescription:(NSMutableArray*)descriptions
{
    if(self = [super initWithNibName:@"DateDescriptionControl" bundle:nil])
    {
        NSMutableArray *tempListOfDates = [[NSMutableArray alloc] init];
        self.listOfDates = tempListOfDates;
        [tempListOfDates release];

        NSMutableArray *tempListOfDescription = [[NSMutableArray alloc] init];
        self.listOfDescription = tempListOfDescription;
        [tempListOfDescription release];
    }
}

in dealloac

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


Just use [object release] to release the instance variable. Using "self" is not necessary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜