在iOS的Objective-C中,当使用合成的getter时,“self.foo”和“foo”之间的(样式)区别是什么?

我已经search了许多关于ObjC访问器和合成访问器的问题无济于事。 这个问题更多的是“帮我解决一个问题”的问题; 我不期待一个答案,但我宁愿寻找专家来衡量论据。

在Cocoa Touch类中,我会写这样的代码(其中soundEffects是一个合成的NSArray属性):

 id foo = [self.soundEffects objectAtIndex:1]; 

一位同事要求我解释为什么上面比这行更好:

 id foo = [soundEffects objectAtIndex:1]; 

那么从function上来说,情况也不例外。

我对前者的论点如下:

  1. self.soundEffects告诉所有其他编码人员在代码上工作,这是一个iVar,而不是一个局部范围的variables。

  2. 如果我们需要的话,我们可以把自定义逻辑放在soundEffects getter访问器中。

  3. 没有具体的原因,在Obj-C工作了一年之后,“觉得”是正确的。

他接受论点#1和#2作为有效的,但也给出了对位:

  1. 这不就是代码膨胀吗?

  2. 不应该允许一个类直接与自己的iVar交谈,而不必自己调用一个方法(getter)?

任何接受者?

你的观点1不是很正确: self.soundEffects 不是一个伊娃,虽然它可能会给你一些东西 – 就像你现在合成NSArray 的情况一样

这又意味着你的观点2是问题的关键 – 如果你通过访问者路由所有的访问,那么一切都很好的封装,你可以随时修改实现,而不必担心副作用。

当你使用mutator时,这也是一个很好的习惯,所以你要保持一致的内存pipe理。

大多数情况下,我认为最好是通过self.property路由self.property的所有东西,并限制直接ivar访问严格内部的东西。 不过,我承认,在某些情况下 – 特别是对于不使用retain / copy语义的东西 – 可能更多的是风格偏好。

我个人决定使用ivars的下划线前缀,这种综合

 @synthesize name = _name; 

这样我不会混淆他们。 不使用自我的主要问题是这个代码

 _name = ... 

是非常不同的

 self.name = ... 

@property使用retain选项。 第一个不保留该对象,第二个调用保留的合成setter。

唯一不同的是分配,所以我倾向于使用self. 所有的时间,所以我确保我做的分配。

使用像self.variable = nil这样的东西使variables通过它的setter,因此得到的内存pipe理是免费的。 如果你只是在dealloc方法中使用variable = nil ,它会导致泄漏,因为它实际上并没有通过variables的合成setter来减less保留计数。 看到这篇文章内存泄漏与自我。

出于这个原因,build议(我相信)总是使用自我。 当处理你所拥有的实例variables时,就内存pipe理而言。

  self.soundEffects 

通过setter / getter设置/获取实例variables,因此,如果我们想要在值更改时执行某些自定义操作,则可以将这个逻辑放在getter / setter中。

也是按照ios 6,伊娃对应的

  @属性(非primefaces)NSArray * propertyName; 

将会

  _propertyName 

所以我想你不能使用

  id foo = [soundEffects objectAtIndex:1]; 

不pipe怎么样,不确定,但你应该使用

  id foo = soundEffects [1];