Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
注意:对于那些四处挖掘试图理解这一点的人,我找出了我困惑的根源。在 .h 中,我有:
...
@interface myClass : parentClass {
className *variableName:
}
@property (strong, nonatomic) className *variableName;
...
这导致 self.variableName 和 _variableName 在 .m 中成为两个不同的变量。我需要的是:
...
@interface myClass : parentClass {
className *_variableName:
}
@property (strong, nonatomic) className *variableName;
...
那么,在类'.m中,self.variableName和_variableName是等价的
在全新的 Xcode 4.5+ 中,使用 ARC,针对 iOS 5.0+ 项目,使用 _variableName
比 self 有明显的优势(运行时效率、速度等) .variableName
与旧式 @synthesize variableName
的对比?
我的理解是 Xcode 4.5+ 将创建一个默认访问器 _variableName
,它等效于 self.variableName
并且是不使用 @synthesize variableName 的唯一原因
是为了避免 iVar 和传入变量之间的混淆,对吗?
对我来说,仅使用 self.variableName
访问 iVar 似乎是最直接和最明确的关于您正在寻找哪个变量的方法。除了键入 _
与 self.
相比,使用 _variableName
是否有优势?
My understanding is that Xcode 4.5+ will create a default accessor "_variableName" that is equivalent to self.variableName and the only reasons not to use "@synthesize variableName" is to avoid confusion between iVars and passed-in variables, correct?
在这种情况下,_variableName
不是访问器,它是由编译器自动生成并在自动@synthesized setter 和getter 中使用的ivar。一般情况下,最好尽可能使用访问器(即 self.variableName
),以便键值观察和绑定(bind)等操作适用于该属性。
当您直接访问一个 ivar 时,它是通过直接内存访问来访问的,就像您访问结构中的数据一样。它只是获取拥有 ivar 的对象的指针,偏移内存地址并尝试读取或写入该位置的内存。使用点符号 (self.variableName
) 调用访问器方法来设置或获取该属性,并且可以在此过程中做很多不同的事情,例如:
1) Locking:如果该属性将在多个线程中使用并且是一个atomic
属性,运行时将自动进行一些锁定以确保不会从多个线程同时访问属性。如果您的对象不打算在多线程上使用,您可以在属性声明中提供 nonatomic
提示,以便合成访问器跳过锁定。
2) Key-Value Notifications:属性的默认 setter 调用 -willChangeValueForKey:
和 -didChangeValueForKey:
,当该属性已更改。如果使用绑定(bind),这对于正确更新任何内容以及任何其他键值观察都是必要的。
3) 自定义访问器行为:如果您最终编写了自己的 setter 和 getter,您在其中实现的任何自定义内容。
从技术上讲,直接访问 ivar 比使用访问器更快,但在极少数情况下它会产生显着的性能差异,并且可能是过早优化的情况。即使您不觉得自己会立即使用上面列出的好处,最好还是使用访问器,这样如果您以后决定需要某些功能,就不必更改每个实例访问该变量(并可能在此过程中产生意想不到的新错误)。
此外,如果您直接访问 ivars 并最终将您的类重构为类别或子类,它会变得困惑,因为您通常必须将 ivar 声明为 @protected
变量。如果您使用访问器,则不必执行此操作。
通常,我尝试只在init
、dealloc
和属性访问器中直接访问ivar。很多工程师都遵循这个经验法则,因为有时访问器中发生的自定义内容会在对象正在init
或dealloc
时导致意外行为。例如,如果访问器中的任何内容导致保留
或释放
您的对象,甚至形成对它的归零弱引用,如果在中使用它会导致崩溃>解除分配
。