问题
Apart from the standard [[MyClass alloc] init]
pattern, some objects are built from static methods like MyClass *obj = [MyClass classWithString:@"blabla"]
According to widespread memory management guides (including Apple's), you're only responsible for releasing the objects that you alloc
.
Can anyone provide me with a template for such methods? How do you return the allocated object ([self alloc]; return self;
, perhaps)? How do you make sure that it will be released?
回答1:
They are class methods, not static methods1. This specific type, creating autoreleased objects, can be referred to as "factory methods" (formerly also "convenience constructors"), and they are discussed in the Concepts in ObjC Guide. They go something like this:
+ (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy {
return [[self alloc] initWithThingummy:theThingummy];
}
Where Whatsis
is your class, and Thingummy
is another class which your class uses.
If you're not compiling with ARC, the convention is to autorelease
the instance before returning it.
The instancetype keyword was introduced by Clang for these kinds of methods; combined with self
(which is the class object itself2 in a class method) it allows correct subclass behavior: the method produces an instance of the class which received the message.3instancetype
allows the compiler to do more strict typechecking than id
.
An illustration of this usage in subclasses from the framework: +[NSString stringWithFormat:]
returns an NSString
instance, whereas +[NSMutableString stringWithFormat:]
, returns an instance of the subclass NSMutableString
, without NSMutableString
being required to explicitly override the method.
As discussed by the [Fundamentals][1] doc, there are other uses for these factory methods, such as accessing a singleton, or appraisal of the necessary memory allocation before it's performed (possible, but less convenient, with a standard alloc
/init
pair).
1"Static methods" in Java or C++, "class methods" in Objective-C. There's no such thing as static methods in ObjC
2Whereas in an instance method self
is, sensibly, a reference to the instance.
3Previously, like the usual initialization methods (initWith...
), you would have used id
as the return type. Using a specific class name unnecessarily forces subclasses to override the method.
回答2:
The objects returned from factory methods should be autoreleased, meaning they'll be cleaned up when the associated autorelease pool is drained. This means that you don't own the returned objects unless you copy
or retain
them. Following is an example of a factory method:
+ (id)myClassWithString:(NSString *)string {
return [[[MyClass alloc] initWithString:string] autorelease];
}
回答3:
These methods are simply returning an autoreleased version of the object.
+(MyClass*)class
{
MyClass* object = [[MyClass alloc] init];
return [object autorelease];
}
回答4:
The modern way to do this with ARC and the latest complier is:
+ (instancetype) myClassWithString:(NSString *)string {
return [[MyClass alloc] initWithString:string];
}
- No need to autorelease with ARC.
- instancetype provides better compile time checks whilst making subclassing possible.
来源:https://stackoverflow.com/questions/5987969/class-methods-which-create-new-instances