1

Is there any performance difference between using class methods and instance methods to initialize an object?

In Apple's docs, I see the following, in the NSArray class (and I have seen this style in other classes too):

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

The descriptions are very similar for each method.

  • Is there a performance difference?
  • Is one better than the other?
  • If they are both the same (in terms of performance), are there any times
    that you would you use one method over the other?

Just curious. :P

4 Answers 4

4

The convenience constructor (+ version) will return an autoreleased value. Under ARC, this autorelease may be optimized away if the result is immediately assigned to a strong reference (using the objc_autoreleaseReturnValue/objc_retainAutoreleasedValue optimization).

The only time you need to be careful is with tight loops where using the + version may lead to lots of autoreleased objects getting created. If profiling reveals this to be a problem, consider using alloc+init instead inside such loops.

In general, you should go with whatever leads to cleaner code, which quite often means using the convenience (+) constructor.

Sign up to request clarification or add additional context in comments.

Comments

0

Is there a performance difference? Is one better than the other?

Not really, but it depends on exactly where you use them and what the surrounding context is.

If they are both the same (in terms of performance), are there any times that you would you use one method over the other?

Personal preference mostly. The differences are in terms of memory management. The class method returns an autoreleased instance and you have no control over the zone it's allocated into. The instance method gives you control over those things.

Generally, and historically, on iOS you would avoid the autoreleased methods because you want to ensure that the memory used by the instance created is cleaned up quickly when you're done with it instead of being left until the pool is drained (because you usually don't know exactly when that will be). ARC reduces this concern though.

Comments

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.

2 Comments

The OP is asking specifically about initializing objects, so the instance methods in question here are init methods
It takes some time to type, you know ;)
0

The only big difference is one give you autoreleased object and other don't.

The autoreleased object remains in the pool till the pool is released.
I love to use non-autoreleased object as whenever I'm finished with that object I just release it. In short you can dispose alloc-init object whenever you want, you just need a reference of this object.

//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
    }
}

Suppose your array takes 1KB, your first two cases will show peak of 1KB as objects are released immediately. In third cases your memory peak will go upto 1000KB and then comes back to zero after auto-released pool is released.

So it depends upon how you code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.