【发布时间】:2010-09-07 06:34:05
【问题描述】:
您可以在 Objective-C 中使用标准点表示法或方法调用来访问 Objective-C 中对象的属性。
myObject.property = YES;
或
[myObject setProperty:YES];
性能(在访问属性方面)是否存在差异?这只是编码风格方面的偏好问题吗?
【问题讨论】:
您可以在 Objective-C 中使用标准点表示法或方法调用来访问 Objective-C 中对象的属性。
myObject.property = YES;
或
[myObject setProperty:YES];
性能(在访问属性方面)是否存在差异?这只是编码风格方面的偏好问题吗?
【问题讨论】:
Objective-C 中属性访问的点表示法是消息发送,就像括号表示法一样。也就是说,鉴于此:
@interface Foo : NSObject
@property BOOL bar;
@end
Foo *foo = [[Foo alloc] init];
foo.bar = YES;
[foo setBar:YES];
最后两行将编译完全相同。唯一改变这一点的是属性是否指定了getter 和/或setter 属性;但是,它所做的只是更改发送的消息,而不是是否发送消息:
@interface MyView : NSView
@property(getter=isEmpty) BOOL empty;
@end
if ([someView isEmpty]) { /* ... */ }
if (someView.empty) { /* ... */ }
最后两行的编译方式相同。
【讨论】:
查看article from Cocoa is My Girlfriend。它的要点是,使用其中一个不会影响性能。
但是,这种表示法确实使您更难看到变量发生了什么以及变量是什么。
【讨论】:
您会看到性能差异的唯一情况是您没有将属性标记为“非原子”。然后@synthesize 会自动在你的属性设置周围添加同步代码,保持线程安全——但设置和访问速度较慢。
因此,您可能想要定义如下属性:
@property(非原子,保留)NSString *myProp;
就我个人而言,我发现点符号通常很有用,因为您不必考虑编写正确的 setter 方法,即使对于非原子 setter,这也不是完全无关紧要的,因为您还必须记住正确释放旧值。使用模板代码会有所帮助,但您总是会犯错误,而且通常是重复的代码会弄乱类。
需要注意的模式:如果您自己定义 setter(而不是让 @synthesize 创建它)并开始产生设置值的其他副作用,您可能应该使 setter 成为普通方法,而不是使用属性调用符号。
语义上使用属性似乎是直接访问调用者的实际值,因此任何与此不同的事情都应该通过发送消息来完成,而不是访问属性(即使它们实际上都在发送消息)。
【讨论】:
据我所见,两者之间没有显着的性能差异。我有理由确定,在大多数情况下,它会被“编译”成相同的代码。
如果您不确定,请尝试编写一个测试应用程序,将每个方法执行一百万次左右,同时计时需要多长时间。这是唯一确定的方法(尽管它可能因不同的架构而异。)
【讨论】:
还可以阅读这篇关于 Cocoa with Love 的博文:
http://cocoawithlove.com/2008/06/speed-test-nsmanagedobject-objc-20.html
作者比较了NSManagedObject的自定义访问器和点符号的速度,并没有发现差异。但是,KVC 访问 (setValue:forKey:) 似乎慢了大约两倍。
【讨论】: