Objective-c – Object allocation from class method

cocoaobjective c

I am just curious if this is right, or bad practice? (i.e. using a class method to alloc/init an instance)? Also am I right in thinking that I have to release the instance in main() as its the only place I have access to the instance pointer?

// IMPLEMENTATION
+(id) newData {
    DataPoint *myNewData;
    myNewData = [[DataPoint alloc] init];
    return myNewData;
}

.

// MAIN
DataPoint *myData;
myData = [DataPoint newData];
... stuff
[myData release];

EDIT:

Also should

myNewData = [[DataPoint alloc] init];

be (or does it not matter)

myNewData = [[self alloc] init];

EDIT_002:

Strange, when I add the autorelease I get …

alt text

EDIT_003:

@Dave DeLong, one final question, what your saying is its perferable to:

+(id) dataPoint {
    return [[[self alloc] init] autorelease];
}

rather than (where you would release in main)

+(id) new {
    return [[self alloc] init];
}

cheers gary

Best Answer

According to naming conventions, you should call it +dataPoint. The reason the analyzer is barfing at you is because (by convention), a class method that uses "new" is expected to return an object with a +1 retain count. You're returning an object with a +0 (autoreleased) retain count, and are therefore breaking convention.

As was alluded to in @Peter's answer, to create an empty object, it's usually done with [ClassName className] methods. Ex: [NSArray array], [NSData data], [NSString string], etc. So the proper thing for you to do would be to rename it [DataPoint dataPoint] and then implement it as return [[[self alloc] init] autorelease];

Using [self alloc] is preferable, since it translates down to subclasses. IE, if you create a MutableDataPoint subclass, then (if you use [self alloc]) doing [MutableDataPoint dataPoint] returns a MutableDataPoint, whereas if you leave it as [DataPoint alloc], it would come back as a DataPoint object (because that's what you're allocating). (On a side note, self refers to the object being operated on in the context of the method. For instance methods, it's the instance. For class methods, it's the Class object itself)

Edit:

If you do want the class method to return an object with a +1 retain count, then (by convention), you'd just need to call it +new (ie, DataPoint * p = [DataPoint new];). However, use of the +new method seems to have fallen into more-or-less disuse, with +alloc/-init... or a class convenience method being the favorable alternatives.

Edit #2 (Re: Edit_003):

I personally prefer the former (+dataPoint), but only because +new isn't as common and I don't have to remember to -release the object. Either one is perfectly acceptable and correct, though.