前几天晚上我在开发游戏时,我意识到我可以通过使用_myObject
而不是self.myObject
.
假设这myObject
是一个属性,由编译器隐式合成,并且已经有一个值,那么底部的会和顶部的做同样的事情吗?
// Non-ARC
self.myObject = [self someValue];
_myObject = [self someValue];
前几天晚上我在开发游戏时,我意识到我可以通过使用_myObject
而不是self.myObject
.
假设这myObject
是一个属性,由编译器隐式合成,并且已经有一个值,那么底部的会和顶部的做同样的事情吗?
// Non-ARC
self.myObject = [self someValue];
_myObject = [self someValue];
这两条线根本不同。前者本质上是对属性的setter方法的方法调用,而后者是直接成员赋值。
当您执行类似的操作self.myObject = x
时,这通常相当于表单的方法调用[self setMyObject:x]
(尽管如果在属性声明中被覆盖,实际的 setter 方法名称可能是其他名称)。
在retain
orcopy
属性的情况下,该方法显然比简单的赋值要多得多。但即使在assign
财产的情况下,也存在重大差异。
当您有一个方法调用时,该方法总是有可能在代码的其他地方被覆盖。在直接分配的情况下,它总是一个分配,没有别的。
通过方法调用,您将自动获得对Key-Value Observing 的支持。通过直接分配,不会生成 KVO 通知。
最后,正如您所注意到的,直接成员分配和调用 setter 方法之间显然存在显着的性能差异。
答案取决于属性的声明:例如,如果myObject
声明为copy
,这两种操作有很大不同:通过属性赋值会复制,而直接赋值给变量不会复制。但是,如果属性是assign
and nonatomic
,它们执行的操作将是相同的。
//for @property (noatomic, retain) NSString* myObject, the setter generated by compiler after synthesize will be like this:
- (void) setMyObject: (NSString*) newObj
{
NSString* temp = [newObj retain];
[_myObject release];
_myObject = temp;
}
//for @property (noatomic, copy) NSString* myObject, setter will be like this:
- (void) setMyObject: (NSString*) newObj
{
NSString* temp = [newObj copy];
[_myObject release];
_myObject = temp;
}
//for @propert (noatomic, assign) NSString* myObject, setter will be like this:
- (void) setMyObject : (NSString*) newObj
{
_myObj = newObj;
}
希望这可以帮助。