NSMutableArray and memory managment

964 Views Asked by At

I am learning Objective C coming from a language which has garbage collection and I am struggling with memory management. In particular I am struggling with what happens in this instance.

// Global variable
NSMutableArray *parentArray;

// Instance
- (void)testing {
  parentArray = [[NSMutableArray alloc] init]; 
  NSMutableArray *childArray = [[NSMutableArray alloc] init];

  [childArray addObject:@"mike"];
  [parentArray addObject:childArray];
}

childArray is a pointer to an array so when I addObject it to the parentArray does it copy it or pass the pointer? If, like I think, it passes the pointer I can't [childArray release] in this method as it would destroy the object and I wouldn't be able to read from it elsewhere.

Therefore do I have to release it in the main dealloc method at the end of the class?

Any help greatly appreicated as I'm struggling.

Mike

5

There are 5 best solutions below

0
On BEST ANSWER

NSMutableArray (and all other standard objective-c containers) retain objects added to them, so you can release your childArray right after it was added to parentArray.

Moreover immediate release will improve your code readability - as it is clear that object ownership passes to the parentArray.

0
On

when you add childArray to the parentArray it is retained once. So, in that point you will have 2 like value in the retain count. Therefore, you can easily release childArray in the method (testing) and keep a reference within the parentArray (retain count = 1). It won't be destroyed then.

0
On

You can release the childArray in the same function, because NSMutableArray retains all the added object.

2
On

addObject: just add object pointer,and retain the object which is added. when removeObject: the array remove the item(pointer),and item will receive the release message.

  • when you NSMutableArray *childArray = [[NSMutableArray alloc] init]; the childArray retainCount is 1.
  • when you [parentArray addObject:childArray]; the childArray retainCount is 2.

when retainCount is 0, and memory not enough, the object will be destroy.

there is same code:

NSMutableArray *parentArray;

parentArray = [[NSMutableArray alloc] init]; 
NSMutableArray *childArray = [[NSMutableArray alloc] init];
NSLog(@"1.childArray retainCount:%d",[childArray retainCount]);
[childArray addObject:@"mike"];
NSLog(@"2.childArray retainCount:%d",[childArray retainCount]);
[parentArray addObject:childArray];
NSLog(@"3.childArray retainCount:%d",[childArray retainCount]);
[parentArray removeAllObjects];
NSLog(@"4.childArray retainCount:%d",[childArray retainCount]);

result:

1.childArray retainCount:1
2.childArray retainCount:1
3.childArray retainCount:2
4.childArray retainCount:1

try it,know it.

0
On

Just add the "autorelease" in the childArray declaration, so that array will be released when possible (childArray so will be released when you release the parentArray that owns that child).

// Global variable
NSMutableArray *parentArray;

// Instance
- (void)testing {
  parentArray = [[NSMutableArray alloc] init]; 
  NSMutableArray *childArray = [[[NSMutableArray alloc] init] autorelease];

  [childArray addObject:@"mike"];
  [parentArray addObject:childArray];
}

- (void) dealloc {
   [parentArray release];
}