使用实例方法和类方法初始化

时间:2013-07-26 13:32:58

标签: ios objective-c macos cocoa-touch

使用类方法和实例方法初始化对象有什么性能差异吗?

在Apple的文档中,我在NSArray类中看到以下内容(我也在其他类中看到过这种风格):

+ (id)arrayWithContentsOfFile:(NSString *)aPath
- (id)initWithContentsOfFile:(NSString *)aPath

每种方法的描述都非常相似。

  • 是否存在性能差异?
  • 一个比另一个好吗?
  • 如果它们都是相同的(就性能而言),是否有任何时间
    你会用另一种方法吗?

好奇。 :P

4 个答案:

答案 0 :(得分:4)

便捷构造函数(+版本)将返回自动释放的值。在ARC下,如果结果立即分配给强引用(使用the objc_autoreleaseReturnValue/objc_retainAutoreleasedValue optimization),则可以优化此自动释放。

唯一需要注意的是紧密循环,使用+版本可能导致大量自动释放的对象被创建。如果分析显示这是一个问题,请考虑在此类循环中使用alloc + init

一般来说,你应该选择更清晰的代码,这通常意味着使用方便(+)构造函数。

答案 1 :(得分:0)

class methodinstance 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,然后在释放自动释放池后返回到零。

所以这取决于你如何编码。