【问题标题】:Best practice regarding accessing instance properties in Objective-C? [duplicate]关于在 Objective-C 中访问实例属性的最佳实践? [复制]
【发布时间】:2012-10-07 06:03:02
【问题描述】:
可能重复:
Difference between self.ivar and ivar?
我想知道,如果我在 Obj-C 中定义一个实例变量作为属性,例如,
@property (copy) NSString *str;
和
@synthesize str = _str;
我应该在实例方法中访问它吗
_str = @"ABC";
或者我应该使用访问器,即
[self setStr:@"ABC"];
有没有关于这方面的一般指导方针?
非常感谢!
【问题讨论】:
标签:
iphone
objective-c
ios
cocoa-touch
cocoa
【解决方案1】:
我有点不同意@Dietrich 画出如此强硬的路线。使用属性 getter 和 setter 非常有效,并提供额外的东西作为好处,例如自动支持键值编码,但是它们也有做额外东西的缺点。作为一种实践,任何外部对象都不应该直接访问对象的成员变量,但是您可以控制和选择是否直接访问和设置类中的成员变量。
直接访问的优点:
1) 更快 - 可能看起来不多,但每次您使用方法而不是直接访问变量时都会产生函数开销 - 在循环中执行此操作,成本并非微不足道。
2) 显式 - 当您设置变量时,您确切知道发生了什么变化
直接访问的缺点:
1) getter 和 setter 上的多态性丢失 - 通过直接访问变量,您将失去子类扩展这些 getter 和 setter 功能的能力,从 OOP 的角度来看,这可能是不可取的(但话又说回来,这也可能取决于你的架构是一个好处)
2) 丢失 KVO(或至少使其更难) - 键值观察可能是一种非常酷的方法,可以将成员变量值的更改绑定到方法回调以导致某种事件驱动的更改(主要是像将属性绑定到 UI 布局/显示)。不过,KVO 并不适合所有人。
3) 失去自动同步(当声明为原子时)——有时你需要你的成员变量是线程安全的。通过删除样板代码,这对属性来说是一个主要好处。
最终,这取决于您作为开发人员。在实践中,我倾向于直接访问成员变量,除非我正在构建一个线程安全的对象,或者在架构上对扩展和 KVO 健壮。
希望对您有所帮助,选择权在您手中! :)
【解决方案2】:
可以读取类内部的实例变量:
NSLog(@"str = %@", _str);
但不要直接设置实例变量:
_str = @"ABC"; // No!
这绕过了您在您的财产上精心设置的copy 机制。所以改为这样做:
[self setStr:@"ABC"]; // Ok
self.str = @"ABC"; // Ok, shorter