Setter method really do in Obj-C?

我的未来我决定 提交于 2019-12-12 04:49:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!