调用“@synthesize slider = _slider;”的重点是什么?

时间:2011-10-11 09:56:24

标签: ios instance-variables

有人可以向我解释创建(似乎是什么)额外变量的重要性,以及为什么在新变量之前放置一个下划线,其名称与最后一个相同。

我已经读过它与创建实例变量有关,但为什么要创建一个UI元素作为实例变量呢?你能提供一个用例吗?

此目标c代码用于iOS开发。

感谢。

3 个答案:

答案 0 :(得分:4)

当你@synthesize属性并且你没有提供自己的getter和setter方法(在这种情况下不需要@synthesize)时,总会创建一个新的实例变量。默认情况下,它与属性的名称相同。所以@synthesize slider;在幕后创建一个名为slider的实例变量。

此处的问题是,当您真正打算使用slider = xxx时,可能会错误地键入self.slider = xxx。当您创建属性时,最佳实践表明您应始终通过self.propertyName访问它(除了在init和dealloc方法以及任何自定义getter和setter方法之外)。

因此,为了避免这种情况,@synthesize语句用于将支持ivar重命名为更难与属性混淆的内容。如果现在使用slider而不是self.slider,编译器将给出错误消息,因为slider不再是实例变量的名称。

答案 1 :(得分:1)

这样做的原因是使实例变量明显地从属性点缀语法中脱颖而出。它还具有避免从参数名称中遮蔽实例变量的实际效果,这在某些情况下也会发生。

在大多数情况下,使用实例变量的原因是为了避免在dealloc中触发KVO。如果你这样做,你就有可能以这样的方式触发KVO:观察者获取传递给它们的释放对象,导致EXC_BAD_ACCESS。

- (void)dealloc
{
    self.slider = nil;
    [super dealloc];
}

因此,通常会这样做,因为您不进行属性访问,所以不会触发KVO。

- (void)dealloc
{
    [_slider release];
    [super dealloc];
}

答案 2 :(得分:1)

这通常用于将属性合成为私有前缀或后缀ivar。它试图阻止你意外地访问ivar而不是属性或用方法参数覆盖ivar。

考虑一下:

@implementation MYClass
@synthesize flag = flag_;

- (void)doSomethingWithFlag:(BOOL)flag {
  if (flag) {
    // You do not need to worry about confusing the ivar
    // flag and the param flag because it is synthesized to flag_
  }
}

- (void)doSomething {
  if (flag) { // Doesn't work -> use accessor self.flag
    ...
  }
}

@end