标题说明了一切!
在Objective-C中,self.propertyName
和propertyName
之间有什么区别?
self.propertyName
向对象发送一条消息,询问propertyName
的值,这意味着它可能会通过getter/setter等。propertyName
绕过任何getter/sette直接访问ivar。这是一篇更详细的文章。
propertyName
指定为保留,则self.propertyName
将保留计数增加一
propertyName不会增加保留计数,这可能导致应用程序崩溃。
e。g.
@property (nonatomic,retain) NSString* propertyName;
假设您有nameProperty
NSString对象。下面将保留计数增加1,您可以使用self.properties名称并调用release
。
self.propertyName = nameProperty;
[nameProperty release];
以下内容不会增加保留计数,因此如果您在应用程序中使用propertyName,将导致应用程序崩溃。
propertyName = nameProperty;
[nameProperty release];
propertyName
的任何进一步使用都将导致崩溃。
self。如果使用属性,则运行可能的合成访问器方法
ie self.properties名称=newName与[self-setPropertyName:newName]相同
这对于内存管理非常重要,因为propertyName=newName会导致您失去对propertyName 以前内容的引用
如果您调用self,您可以确定您正在调用拥有该属性的类/对象。
你可能会发现这也很有用:
在Objective-C 中分配给self
点表示法由编译器转换为方法调用。这意味着在运行时执行这个方法调用需要额外的工作,比如从堆栈内存中复制一些东西并将其复制到堆栈内存中,以及执行机器代码中的跳转。
实例变量本身速度更快,因为它本质上只是一个内存地址或标量值(如int)。
当你想要或需要一个额外的层来做某事时,人们会更喜欢self.something符号。比如保留传入的对象,或者在第一次需要时延迟实例化对象
设置属性值就是这样做的——它直接设置属性值,而不需要经过任何访问器或合成访问器。
通过self
调用访问器,就是在遍历访问器。对于已经用retain
或copy
声明的属性,它将retain
或copy
作为传入的值。对于非对象属性,通常的声明是assign
,这意味着没有对这些iVar应用内存管理。
您可以看到这两种类型的调用,但最好在初始化程序中使用direct方法和dealloc
方法,因为在这些方法中不鼓励调用self
。
如果您已经声明并合成了属性,那么对self
的调用也会为该变量中的更改生成KVO通知。这样就不用编写willChangeValueForKey:
和didChangeValueForKey:
方法了。