ios 正确覆盖 Objective-C 中的 setter

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12369787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:03:07  来源:igfitidea点击:

Correctly override setter in Objective-C

iphoneobjective-cios

提问by E. Lüders

I just tried to override the standard synthesised setters of a property. So far everything is fine I just set the ivar to my new value. But then I asked myself 'what happens with the retain count of retained properties'... I found no good answer that explained this to me. So I ask it here. Is there anything I have to be aware of if I override a properties setter that is set to retainand how can I do it correctly? I do not use ARC.

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

Here's an example:

下面是一个例子:

@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?
}

回答by Hot Licks

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

If you release the old pointer before retaining the new, you can have a situation where you're setting the value from a value in the old object, and the release of the old object causes the new object to go POOF! just before it's retained.

如果在保留新指针之前释放旧指针,则可能会出现从旧对象中的值设置值的情况,而旧对象的释放会导致新对象变成 POOF!就在它被保留之前。

Alternatively, you could do

或者,你可以做

....
[someObject retain];
[_anObject release];
_anObject = someObject;
...

回答by Thomas Johannesmeyer

Are you overwriting the setters just to have a different name? If that's the case you can do so by changing the property definition:

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

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

Same works for getter.

吸气剂也一样。

回答by Damo

Edited after studying accepted answer from Hot Licks

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

property declaration and synthesis of x

x 的属性声明和合成

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

over-ridden setter for x

x 的重载 setter

- (void)setX:(ClassX *)x;
{
  if (x != _x)
  {
    [x retain];
    [_x release];
    _x = x;
    // custom code here
  }
}

回答by Amy Worrall

- (void) setSomething:(NSObject*) something
{
    if (something != _something)
    {
        [_something release];
        _something = [something retain];
    }
}

You need the ifstatement because otherwise, if something and _something were alreadythe same, you'd overrelease the object, have it possibly disappear, and have problems.

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