使用类方法和实例方法初始化对象有什么性能差异吗?
在Apple的文档中,我在NSArray类中看到以下内容(我也在其他类中看到过这种风格):
+ (id)arrayWithContentsOfFile:(NSString *)aPath
- (id)initWithContentsOfFile:(NSString *)aPath
每种方法的描述都非常相似。
好奇。 :P
答案 0 :(得分:4)
便捷构造函数(+
版本)将返回自动释放的值。在ARC下,如果结果立即分配给强引用(使用the objc_autoreleaseReturnValue/objc_retainAutoreleasedValue
optimization),则可以优化此自动释放。
唯一需要注意的是紧密循环,使用+
版本可能导致大量自动释放的对象被创建。如果分析显示这是一个问题,请考虑在此类循环中使用alloc
+ init
。
一般来说,你应该选择更清晰的代码,这通常意味着使用方便(+
)构造函数。
答案 1 :(得分:0)
class method
和instance method
之间的区别在于
instance方法需要一个类的实例
(一般)操作。必须是要调用实例方法的消息
发送到一个类的实例。
For example
在Cocoa中,NSString类有几个名为的类方法
stringWithSomethingOrOther:这将创建一个新的NSString对象和
把它交还给你。
另一方面,NSString 也有很多实例方法 - 在没有实际实例的情况下真正没有意义的操作 与...合作。一个常用的可能是长度方法,它告诉我们 您在特定NSString实例中有多少个字符 邮件已发送。
假设另一个例子 -
@interface DeepsClass : NSObject
+ (void)myClassMethod;
- (void)myInstanceMethod;
@end
现在可以像这样使用: -
[DeepsClass myClassMethod];
DeepsClass *object = [[DeepsClass alloc] init];
[object myInstanceMethod];
<强> Performance difference
强>
课程方法中的表现 almost the same
&amp;实例方法。类方法在运行时像任何其他方法一样处理(例如,实例方法),并且Class可以在运行时加载,方法本身是C函数,与实例方法相同,并且这些函数的POINTERS被缓存,就像实例方法。
答案 2 :(得分:0)
是否存在性能差异? 一个比另一个好吗?
不是真的,但这取决于你使用它们的具体位置以及周围环境的含义。
如果两者都相同(就性能而言),是否有任何时间 你会用另一种方法吗?
主要是个人偏好。差异在于内存管理。 class方法返回一个自动释放的实例,你无法控制它分配的zone
。实例方法可以控制这些事情。
通常,在历史上,在iOS上,您可以避免使用自动释放的方法,因为您希望确保创建的实例使用的内存在完成后快速清理,而不是在池耗尽之前将其保留(因为你通常不确切知道什么时候会这样做。 ARC虽然减少了这种担忧。
答案 3 :(得分:0)
唯一的区别是一个给你自动释放的对象而另一个则没有。
自动释放的对象保留在池中,直到池被释放 我喜欢使用非自动释放的对象,因为每当我完成该对象时,我就会释放它。简而言之,您可以随时处理alloc-init对象,只需要引用此对象。
//case 1:
for (int i = 0; i<1000; i++) {
NSArray *array = [[NSArray alloc] initWithContentsOfFile:@"path"];
//Do something with array
[array release];
}
//case 2:
for (int i = 0; i<1000; i++) {
@autoreleasepool {
NSArray *array = [NSArray arrayWithContentsOfFile:@"path"];
//Do something with array
}
}
//case 3:
@autoreleasepool {
for (int i = 0; i<1000; i++) {
NSArray *array = [NSArray arrayWithContentsOfFile:@"path"];
//Do something with array
}
}
假设你的数组需要1KB,你的前两个案例会在对象立即释放时显示1KB的峰值。在第三种情况下,您的内存峰值将达到1000KB,然后在释放自动释放池后返回到零。
所以这取决于你如何编码。