有关在Objective-C中访问实例属性的最佳实践?

时间:2012-10-17 03:11:19

标签: iphone objective-c ios cocoa-touch cocoa

  

可能重复:
  Difference between self.ivar and ivar?

我想知道,如果我在Obj-C中将实例变量定义为属性,例如,

@property (copy) NSString *str; 

@synthesize str = _str; 

我应该通过

在实例方法中访问它
_str = @"ABC";

或者我应该使用访问者,即

[self setStr:@"ABC"];

有关于此的一般指导原则吗?

非常感谢!

2 个答案:

答案 0 :(得分:7)

可以从类中读取实例变量:

NSLog(@"str = %@", _str);

但是不要直接设置实例变量:

_str = @"ABC"; // No!

这会绕过你小心翼翼地放置在你房产上的copy机制。所以这样做是这样的:

[self setStr:@"ABC"]; // Ok
self.str = @"ABC";    // Ok, shorter

答案 1 :(得分:2)

我有点不同意@Dietrich画这么强硬的一句话。利用属性getter和setter是非常有效的,并提供额外的东西作为一个好处,如自动支持键值编码,但它们也有做额外的东西的缺点。实际上,没有外部对象应该直接访问对象成员变量,但是您可以控制和选择是否直接访问和设置类中的成员变量。

PROS直接访问:

1)速度更快 - 看起来似乎并不多,但每次使用方法而不是直接访问变量都会导致函数开销 - 在循环中执行此操作并且成本并非无关紧要。

2)显式 - 你知道在设置变量

时究竟发生了什么变化

CONS直接访问:

1)getter和setter上的多态性丢失 - 通过直接访问变量,你失去了子类扩展那些getter和setter的功能的能力,从OOP的角度来看这可能是不可取的(但同样,也可能取决于您的架构,这是一个好处)

2)KVO的丢失(或者至少使其变得更难) - 键值观察可以非常酷的方式将成员变量值的变化绑定到方法回调以引起某种事件驱动的变化(大多数情况下像将属性绑定到UI布局/显示)。 KVO并不适合所有人。

3)自动同步丢失(当声明为原子时) - 有时你需要你的成员变量是线程安全的。通过它们去除锅炉板代码,这对于物业来说是一个主要的好处。

最终,这取决于您作为开发人员。在实践中,我倾向于倾向于直接成员变量访问,除了当我构建一个线程安全的对象或者在体系结构上强大的扩展和KVO时。

希望这有帮助,选择权归你的! :)