iOS中的默认setter


- (void)setSomeInstance:(SomeClass *)aSomeInstanceValue
{
    if (someInstance == aSomeInstanceValue)
{
    return;
}
SomeClass *oldValue = someInstance;
someInstance = [aSomeInstanceValue retain];
[oldValue release];
}

好的,所以setter应该看起来像。我理解前三行——当新对象和旧对象相同时,防止出现之前的情况。但是这条线呢:

SomeClass *oldValue = someInstance;

为什么系统必须保留旧对象的地址。为什么不能简单的

  [someinstance release];
   someinstance = [aSomeInstanceValue retain];

实际上-没有原因。

这通常只是一种选择。

有三个用于书写访问者的习语。

自动发布

- (void)setFoo:(id)newFoo {
    [foo autorelease];
    foo = [newFoo retain];
}

要写的代码更少,但我认为在这种情况下自动释放是懒惰的。

保留然后释放

- (void)setFoo:(id)newFoo {
    [newFoo retain];
    [foo release];
    foo = newFoo;
}

首先检查

- (void)setFoo:(id)newFoo {
    if ([foo isEqual:newFoo]) {
        return;
    }
    [foo release];
    foo = [newFoo retain];
}

后两者之间唯一的区别是,第二个在尝试设置属性之前检查新值是否与当前值不同。以额外的if语句为代价。因此,如果新值可能与旧值相同,则使用此构造可以获得更好的性能。

一般来说,如果您出于某种奇怪的原因没有使用属性,请先使用retain,然后再使用release,如果分析显示存在瓶颈,请使用check first方法。

我建议默认的retain setter的工作方式如下:

- (void) setFoo:(id) foo {
    if ( foo == _foo) return;
    [_foo release];
    _foo = [foo retain];
}

如果你不检查旧的和新的foo是否相同,如果你出于某种原因写了这样的东西,你可能会引用一个被释放的对象:

myObject.foo = myObject.foo;

因为同一个对象会先被释放,然后被保留。如果myObject是唯一的所有者,那么该对象将在第一次发布后被释放,留下一个悬空指针。

默认的保留设置程序的工作方式如下:

- (void)setFoo:(Foo *)aFood
{
    if (_foo != nil)
       [_foo release];
    if (aFood != nil)
       _foo = [aFood retain];
}

相关内容

  • 没有找到相关文章

最新更新