2012-07-31 57 views
2

这里有很多关于为什么要通过@synthesized setter(而不是直接访问伊娃),保留/复制内存管理或KVO。使用@synthesized getter有什么意义?

但我想不出为什么你会在意如果你使用foo = self.barfoo = bar的好论据。

我能想到的唯一的事情就是数据抽象......如果bar是一个声明的属性,那么底层的实现可能会改变,没有人会关心。 (当然,在这种情况下,你可能不会使用@synthesized getter)

因此......使用@synthesized getters的任何令人信服的理由?是否有一些线程问题使其变得重要?

对于这个问题,@synthesized代码甚至可以做什么,除了返回伊娃吗?

回答

2

一个很好的理由是封装。当你浏览访问器时,这个类可以自由地在界面后面做任何想法(正如你在问题中所说的那样)。该值可能会被延迟取出,可能会立即计算或从其他对象取得。也就是说,在类实现中,我通常使用普通的ivar访问,因为如果属性实现发生更改,我可以自由地重写。 (当私有ivars在公共头部被声明时,这是一个更大的问题,以便你的子类可以直接访问它们。)

至于线程,我认为默认的getter/setter组合是原子的,这意味着你不能得到一个在setter中间调用getter的bug,会得到一些无效的值。我从来没有读过这个问题,请查看nonatomic属性修改器的文档。 (或者this related question

+0

你的懒加载的例子,虽然将需要一个自定义getter ...不是@synthesized之一。我当然可以看到自定义获得者的需要。线程安全点是一个好的选择。 – wrjohns 2012-07-31 12:05:07

+1

问题是,如果现在不使用合成的getter,而是直接使用ivar访问,那么以后不能更改实现(例如,通过添加延迟加载),而不必重写所有对ivar的访问。这可能是一个问题,如果直接ivar访问泄漏到您的子类或甚至您的API用户。 – zoul 2012-07-31 14:01:02

+0

啊,我明白你的意思了。 – wrjohns 2012-07-31 14:14:45

1

该getter还需要符合@property语句中定义的内存管理规则;例如,如果它有retain属性它需要使用autorelease

- (NSString *)name 
{ 
    return [[_name retain ] autorelease]; 
} 

,并让它从合成不必键入它可以节省你。另外能够合成吸气剂和吸气剂是更完整的解决方案。

+2

据'[_name保留]自动释放]' – hamstergene 2012-07-31 06:53:45

+0

@hamstergene谢谢 - 仍然在我的咖啡 – trojanfoe 2012-07-31 06:54:41

+1

刚一说明第一杯:如果您编制了“内存管理规则”的说法并不适用与ARC。 'foo = bar'将永远“做正确的事情”。 – 2012-07-31 08:08:17