views:

60

answers:

3

This is an example straight from Apple's documentation -

@implementation MyClass

- (id)initWithString:(NSString *)aName
{
    self = [super init];
    if (self) {
        name = [aName copy];
    }
    return self;
}

+ (MyClass *)createMyClassWithString: (NSString *)aName
{
    return [[[self alloc] initWithString:aName] autorelease];
}
@end

As I would be creating a new MyClass Object in each case anyway, I want to know why I might use the Class Method createMyClassWithString:aName instead of the Instance Method initWithString:aName

Thanks

A: 

The only reason is readable and beautiful code...

In addition, in your example the class method returns an autoreleased instance...

Michael Kessler
OK, so if that's the only benefit and because Apple recommend that with iPhone programming you should try to avoid autorelease where possible...I presume that I should forsake code-beauty and stick to using Instance Methods when writing iOS code? Cheers
kungpoo
A: 

The short, unhelpful answer would be: where is makes sense. Neither is more correct; neither is wrong.

An example might be more use. I would use the class method if I was returning the value from a method:

- (MyClass*) doStuff {
  MyClass* retv = [MyClass createMyClassWithString:@"Simon says"];
  [retv someOtherMethod];
  return retv;
}

By convention you return autoreleased objects, so using the class method results in slightly less typing.

Stephen Darlington
A: 

I always use the class method where possible because it results in less verbose code and if you are simply going to return the object to the caller you'd have to autorelease it anyway, if you obtained it with alloc.

The advice from Apple was poorly worded, in my opinion. People seem to be taking it as a blanket ban on autorelease. That's simply not the case. You just have to be mindful that autorelease comes withy a memory price, but it is not as high as you might think. Each runloop event except timer events comes with a new autorelease pool that gets drained on return to the runloop. So if you know the method is going to be quick there's no problem. Also, if an object is going to outlive the current event, there's no issue because the overhead ofd an object in an autorelease pool is quite small and draining the pool won't dealloc the object anyway.

The only case where you need to be careful about putting objects indiscriminately in the autorelease pool is where you have intensive processing creating lots of temporary autoreleased objects. You can relieve the pressure of these methods by creating autorelease pools and draining them as you go along. e.g.

while(someCondition)
{
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

    // intensive processing

    [pool drain];
}
JeremyP