问题
Here is implement of a setter method:
- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}
If retainCount
of _count
is <=0, how it can release ?
回答1:
The only valid object that can ever have a retain count of 0 is nil
. And sending any message to nil
just returns 0 without doing anything else, so that case is covered.
If you mean "how can this work with a deallocated object" — well, it can't. And a deallocated object's retain count isn't really 0, because the object doesn't exist anymore — it's been destroyed and is now just a chunk of memory — so it doesn't have any attributes. Doing anything with a deallocated object is invalid and what will happen is undefined.
回答2:
Imagine a class with a retainCount
instance variable.
@implementation MyClass
{
NSUInteger retainCount;
}
- (id) retain {
retainCount++;
return self;
}
- (void) release {
if (retainCount > 1)
retainCount--;
else
[self dealloc];
}
...
@end
Once an object is deallocated, it is dead, gone, done for, etc... Thus, there is no point in ever decrementing the retainCount to 0 because, by definition, the object is going to be deallocated and working with a deallocated object is undefined behavior.
The above is the exact logic of NSObject, but a completely different implementation (you really wouldn't want to see NSObject's actual implementation -- it is quite painful).
The other source of confusion appears to be what a reference means.
NSObject *foo;
char *bar;
NSUInteger baz;
For all intents and purposes, the above three variable declarations behave identically [in manual retain/release].
When you say bar = "Hello, World!";
, you are telling the compiler 'copy the address of the memory that holds the string "Hello, World!" into the memory named bar
". Same for foo
, only you are copying the address of memory that holds an instance of the class NSObject
.
Now, baz
may seem different. But it really isn't except that it holds numbers, not addresses. But, really, an address is a number!
So, in a setter::
- (void)setCount:(NSNumber *)newCount {
// increment newCount's retain count
[newCount retain];
// decrement the _count's retain count (which may cause it to be deallocated or not)
[_count release];
// copy the address of the memory that holds the NSNumber instance referenced
// by `newCount` into the instance variable `_count`.
_count = newCount;
}
There is nothing magical about that assignment [under manual retain release]. It is just copying a number from one variable to the other. The objects are not impacted at all by this.
来源:https://stackoverflow.com/questions/15908288/setter-method-really-do-in-obj-c