19

我只是试图覆盖一个属性的标准合成设置器。到目前为止一切都很好,我只是将 ivar 设置为我的新值。但是后来我问自己'保留属性的保留计数会发生什么'......我没有找到可以向我解释这一点的好答案。所以我在这里问。如果我覆盖设置为的属性设置器,我必须注意什么,我该retain如何正确地做到这一点?我不使用ARC。

这是一个例子:

@property(nonatomic)NSInteger number;

- (void)setNumber:(NSInteger)number {
    _number = number;  // This should be fine, since it's no retained object I want to set
}


@property(nonatomic, retain)NSObject *something;

- (void)setSomething:(NSObject *)something {
    _something = something;  // This is not fine. As far as I know you should never do sth. like this... But how do I set it correctly?
}
4

4 回答 4

29
-(void) setAnObject:(NSObject*) someObject {
    if (_anObject != someObject) {
       NSObject* savedObject = _anObject;
       _anObject = [someObject retain];
       [savedObject release];
    }
}

如果您在保留新指针之前释放旧指针,您可能会遇到这样一种情况,即您正在从旧对象中的值设置值,而旧对象的释放会导致新对象POOF!就在它被保留之前。

或者,你可以做

....
[someObject retain];
[_anObject release];
_anObject = someObject;
...
于 2012-09-11T12:46:34.593 回答
5

您是否只是为了使用不同的名称而覆盖设置器?如果是这种情况,您可以通过更改属性定义来做到这一点:

@property(nonatomic, setter = nameOfSetter: )NSInteger number;

同样适用于吸气剂。

于 2012-09-11T12:38:08.350 回答
5

在研究了 Hot Licks 接受的答案后编辑

x的属性声明和综合

@property (nonatomic, retain) ClassX x;
@synthesize x = _x;

x 的重载设置器

- (void)setX:(ClassX *)x;
{
  if (x != _x)
  {
    [x retain];
    [_x release];
    _x = x;
    // custom code here
  }
}
于 2012-09-11T12:39:26.897 回答
4
- (void) setSomething:(NSObject*) something
{
    if (something != _something)
    {
        [_something release];
        _something = [something retain];
    }
}

您需要该if语句,因为否则,如果 something 和 _something已经相同,您将过度释放该对象,使其可能消失并出现问题。

于 2012-09-11T12:39:52.217 回答