Take the 2-minute tour ×

I'm new, but I read a lot about memory management, and really tried to find the answer myself. It sounds so basic and yet I apparently don't get it. I have a NSMutableArray as property in .h:

@property (nonatomic, retain) NSMutableArray *documentListArray;

I synthesize it and release it in (void) dealloc. To populate the array, I have a method - (void)updateRecordList and in there:

self.documentListArray=[DocumentDatabase getDocumentListSortedByDate];

EDIT:next line:

[[self recordListTableView] reloadData];

where DocumentDatabase is a different class with the class methods getDocumentListSortedByDate and getDocumentList. Here is what is happening in getDocumentListSortedByDate:

NSMutableArray *returnArray = [DocumentDatabase getDocumentList];
NSLog("array count:%i",[returnArray count]); //returns correct numbers first and second time
return returnArray;

and in getDocumentList

NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:files.count];
//add file data to array...
return returnArray;

This works the first time I call updateRecordList, but after adding a file and calling updateRecordList a second time, it crashes with (using NSZombies): * -[NSCFNumber dealloc]: message sent to deallocated instance 0x7504c90. With a lot of logging I narrowed the problem down to the line above in updateRecordList and it works if I change it to:

self.documentListArray=[[DocumentDatabase getDocumentListSortedByDate] retain];

My conclusion is that the array down in getDocumentList has been autoreleased before it arrives. So my questions are:
1. Why do I have to retain it there? Shouldn't that happen by itself by declaring the property (retain)? Or, in other words, why is the array autoreleased too early (assuming this is what is happening)?
2. When I assign a new array to self.documentListArray, is the old array automatically released? If I try to release it myself before getting a new documentList, it crashes too.

Thanks in advance for any reply.

EDIT: Maybe I'm an idiot: I failed to mention that documentListArray is the data source for an UITableView (see the added line on top). I suspect that I am doing something wrong with populating the table view, and the array gets retained...? It does however crash on assigning the property, not on reloadData. I go back to study if I use the UITableViewDataSource protocol properly. Thanks to everybody, your answers brought me hopefully on the right track. Will update when solved.

EDIT2: It works now without retaining, and I think I understand why: I debugged extensively and found that Objects contained in Objects added to the array where nil. Particularly, deep down in encodeWithCoder I did not use "self" when assigning values. When decoding, those values where nil. Since I changed that, it seems to work. I suspect that not assigning the new array caused the crash, but the TableView which would read the new array-even before I call reloadData. Which would lead back to Davids question of synchroneous access. Thank you all for your help.

share|improve this question
Did you write your own setter? –  FelixLam Nov 15 '10 at 13:17
I don't think this is your problem, but you should release documentListArray, not dealloc it, in your -dealloc method –  David Gelhar Nov 15 '10 at 13:19
That was quick, amazing! @Felix, no, I don't have my own setter just the property-synthesize pattern. @David, I used wrong terminology, I do "release" it actually-will edit this now. –  marimba Nov 15 '10 at 13:26
Could you show us what [DocumentDatabase getDocumentListSortedByDate] returns (i mean in terms of alloc/retains and releases)? –  FelixLam Nov 15 '10 at 14:18
Gladly, but how? Do you want me to NSLog the retain count? Also, should I post this in a comment or in the original post? –  marimba Nov 15 '10 at 14:25
show 1 more comment

1 Answer

up vote 1 down vote accepted
  1. The code you've shown it appears correct; it should not be necessary (or correct) to call retain yourself, as long as you are assigning the value to a property with retain semantics before the autorelease pool is drained. Are all the calls (getDocumentListSortedByDate, getDocumentList) happening synchronously, or are you doing any of this in the background? Double-check that you're assigning using the "self." ("self.documentListArray =") instead of just assigning directly to the instance var ("documentListArray ="); if you omit the "self.", the setter is bypassed.

  2. No, don't free the old value before assigning; that's the setter's job.

share|improve this answer
Thank you for your answer. I double checked and I use indeed self.documentListArray. Also, updateRecordList is the only place where I change the array, all other places just use it. I believe it is happening synchroniously, as it is called in the linear way as shown above. But I am not knowledgeable enough to be absolutely certain. BUT maybe it has to do with that the methods in DocumentDatabase are class methods? –  marimba Nov 15 '10 at 13:37
Reviewing my post, I realize that it is probably not obvious that DocumentDatabase is another class. Now this is probably a real noob question: Does that matter to the autorelease pool? –  marimba Nov 15 '10 at 13:55
No, that shouldn't matter. –  David Gelhar Nov 15 '10 at 14:08
add comment

Your Answer


