cyclingIsBetter
cyclingIsBetter

Reputation: 17591

iOS - Question about Memory management : NSArray case

I have this code:

- (void) firstMethod{
NSString *first = @"Hello";
NSString *second = @"World";
NSArray *myFirstArray = [[NSArray alloc] initWithObjects: first, second, nil];
[mySecondArray addObject :myFirstArray];
[myFirstArray release];
}

when I do release of myFirstArray, can I lose my two string? or they remain stored in mySecondArray?

Upvotes: 1

Views: 791

Answers (2)

Oliver
Oliver

Reputation: 23510

First and second have a retain count of 1 (made autorelease) when creating the objects.
Each object added to an array has it's retain count raised.

So when adding first and second to firstArray, their retain count is raised to 2 (with 1 of autorelease). When adding these objects from firstArray to secondArray, nothing happens with firstArray, but first and second are found into firstArray and added again into secondArray, so their retain count is again raised, to 3 (including 1 of autorelease).

If you release first Array, its own retain count is decreased, and each object it "contains" has its retain count decreased too. So the array has its retain count at 0 and is deleted from memory. First and second have their retain count decreased to 2 (including 1 of autorelease).

If you wait some time, the autorelease effects is triggered, and first and second have their retain count decreased by 1, so they have a retain count of 1, the one that has been set when adding first and second from firstArray into secondArray.

Just keep in memory that the array does not contain any object but references (pointers if you prefer) to objects that are outside the array.

if you write :

NSArray *myFirstArray = [[NSArray alloc] initWithObjects: @"test1", nil];

it creates a string object, put test1 into it, put its retain count at 1, and make it autorelease. Then the memory address of the object is inserted into the array, that has also it's own retain count set to 1.

Said in another way, myFirstArray is a pointer to an array of pointers, where each object has its own retain count.

EDIT : the desciption given is for addObjectsFromArray:
I've read again the question and I see that the question is for addObject:

So the receipe is the same. Let's say that the Retain Count is in parenthesis and AR means autorelease :

NSString *first = @"Hello";
NSString *second = @"World";

first (1 AR)
second (1 AR)

NSArray *myFirstArray = [[NSArray alloc] initWithObjects: first, second, nil];

myFirstArray (1)
first (1 AR + 1)
second (1 AR + 1)

[mySecondArray addObject :myFirstArray];

mySecondArray (1 AR, assuming it's created with [NSMutableArray array]; that is missing)
myFirstArray (1 + 1) retained by the call
first (1 AR + 1) no change
second (1 AR + 1) no change

[myFirstArray release];

mySecondArray (1 AR) no change
myFirstArray (1) -1, but still living
first (1 AR + 1) no change
second (1 AR + 1) no change

Hope that's clear :-)

Let's imagine You wait some time.

  • The autorelease of mySecondArray is triggered :
    mySecondArray (0) KILL

  • then myFirstArray receive a release
    myFirstArray (0) KILL

  • then each object into myFirstArray receive a release
    first (1 AR) -1, but still living a short time
    second (1 AR) -1, but still living a short time

  • Wait some time for the next event loop, then the autorelease of the strings are triggered :
    first (0) KILL
    second (0) KILL

Upvotes: 3

AWF4vk
AWF4vk

Reputation: 5890

They aren't stored by the second array, but your first array will be retained by the second array.

Meaning, when you call release on the first array, it won't be released until the array is removed from the second array.

Second array retains the first array. The first array retains the strings.

Upvotes: 1

Related Questions