1

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

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

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

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

  • 有性能差异吗?
  • 这个比那个好吗?
  • 如果它们都相同(就性能而言),
    您是否会在任何时候使用一种方法而不是另一种方法?

只是好奇。:P

4

4 回答 4

4

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

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

一般来说,你应该使用任何可以使代码更简洁的方法,这通常意味着使用便利 ( +) 构造函数。

于 2013-07-26T13:40:42.837 回答
0

The difference between a class method and an instance method is that an instance method requires an instance of the class on which it will (generally) operate. The message to invoke an instance method must be sent to an instance of a class.

For example In Cocoa the NSString class has several class methods named stringWithSomethingOrOther: that will create a new NSString object and hand it back to you.

On the other hand, NSString also has many instance methods - operations which really have no meaning without an actual instance to work with. A commonly-used one might be the length method, which tells you how many characters are in the specific NSString instance to which the message is sent.

Suppose for another example-

@interface DeepsClass : NSObject 

+ (void)myClassMethod; 
- (void)myInstanceMethod; 

@end

It can now be used like this : -

[DeepsClass myClassMethod]; 

DeepsClass *object = [[DeepsClass alloc] init]; 
[object myInstanceMethod];

Performance difference

Performance is almost the same in class methods & instance methods. Class methods are treated at runtime like any other methods (eg. instance methods), and while the Class may be loaded at runtime, the methods themselves are C functions, same as instance methods, and the POINTERS to those functions are cached, just like instance methods.

于 2013-07-26T13:37:10.847 回答
0

有性能差异吗?这个比那个好吗?

不是真的,但这取决于你在哪里使用它们以及周围的环境是什么。

如果它们都相同(就性能而言),您是否会在任何时候使用一种方法而不是另一种方法?

主要是个人喜好。区别在于内存管理。类方法返回一个自动释放的实例,您无法控制zone它的分配。实例方法使您可以控制这些事情。

一般来说,从历史上看,在 iOS 上,您会避免使用 autoreleased 方法,因为您希望确保创建的实例使用的内存在您完成后被快速清理,而不是一直等到池耗尽(因为您通常不知道具体是什么时候)。不过,ARC 减少了这种担忧。

于 2013-07-26T13:42:46.793 回答
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,然后在自动释放池释放后恢复为零。

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

于 2013-07-26T13:53:19.490 回答