开发者

Set an object to nil after added them to a container?

I thought that NSArray/NSDictionary/NSSet and their mutable subclasses just added the pointer to the object, and not the object it self.

So if set my "simple" object to nil after I added it to the container, why isn't the reference nil also in the Array (container)?

Here is the code:

NSMutableArray *array = [[NSMutableArray alloc] init];

Simple *simple = [[Simple alloc] init];
[array addObject:simple];

//Array sends retain, lets release
[simple release], simple = nil;

NSLog(@"Simple = \"<Simple: %p>", simple);
NSLog(@"Array: %@", array);

[array release], array = nil;

Here is the output:

2011-02-16 20:00:03.149 Allocations[5433:207] Simple = <Simple: 0x0>
2011-02-16 20:00:03.150 Allocations[5433:207] Array: (
    <Simple: 0x4d3d4e0>开发者_开发问答;
)


NSArray adds a pointer to the object. In order to track changes to variable, the array would have to add a pointer to the variable itself (remember, you're just setting the variable to nil, not the object). There can be many variables all pointing to the same object, and reassigning them won't change any others.

Remember: Pointers aren't magic. They're just ordinary variables whose value is a memory address — in this case, the memory address of an object. Two pointers to the same object aren't "linked" any more than two ints with the value 5. Changing the pointer doesn't affect the object; in order to affect the object, you have to either send it a message that causes it to change (e.g. [object setValue:6]) or dereference the pointer to access the object's members directly (e.g. object->value = 6).

PS: Don't access an object's members directly. It's bad and fragile and very prone to bugs. I just mentioned it here to explain how pointers work.


Setting simple = nil just makes that pointer point to nothing. It doesn't delete the object that the array still has a pointer to. At the point of your NSLog statements, the retainCount of the Simple instance that simple pointed to would be one.

Create simple

  • simple => (Simple instance: retain count 1)

Add to array

  • simple => (Simple instance: retain count 2)

  • [array objectAtIndex:0] => (Simple instance: retain count 2)

Release simple

  • simple => (Simple instance: retain count 1)

  • [array objectAtIndex:0] => (Simple instance: retain count 1)

Set simple = nil

  • simple => nil

  • [array objectAtIndex:0] => (Simple instance: retain count 1)

Release array

  • (Simple instance: retain count 0, subsequently destroyed)


NSArray does contain only a pointer to the object that is added, but that's ok -- it's not pointing to the simple pointer itself, but rather to the Simple object that simple pointed to. Thus in your example, after you change what simple points to, the array is still pointing at the original Simple object.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜