创建新实例的类方法

时间:2011-05-13 06:18:09

标签: objective-c memory-management class-method initializer

除标准[[MyClass alloc] init]模式外,某些对象是使用静态方法构建的,如MyClass *obj = [MyClass classWithString:@"blabla"]

根据广泛的内存管理指南(包括Apple),您只负责发布alloc的对象。

有人能为我提供这种方法的模板吗?你如何返回分配的对象(也许是[self alloc]; return self;)?你如何确保它会被释放?

4 个答案:

答案 0 :(得分:48)

它们是类方法,而不是静态方法 1 。创建自动释放对象的这种特定类型可以称为“工厂方法”(以前也称为“便利构造函数”),它们在the Concepts in ObjC Guide中讨论。他们是这样的:

+ (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy {
    return [[self alloc] initWithThingummy:theThingummy];
}

Whatsis是您的班级,Thingummy是您班级使用的另一个班级。

如果您没有使用ARC进行编译,那么在返回之前,约定是autorelease实例。

Clang为这些方法引入了instancetype keyword;结合self(在类方法中是class object本身 2 )它允许正确的子类行为:该方法生成接收消息的类的实例。 sup> 3 instancetype允许编译器执行比id更严格的类型检查。

来自框架的子类中此用法的说明:+[NSString stringWithFormat:]返回NSString实例,而+[NSMutableString stringWithFormat:]返回子类NSMutableString的实例,而不NSMutableString 1}}需要显式覆盖方法。

正如[基础] [1] doc所讨论的那样,这些工厂方法还有其他用途,例如访问单例,或者在执行之前评估必要的内存分配(可能,但是方便,标准alloc / init对。


1 Java或C ++中的“静态方法”,Objective-C中的"class methods"There's no such thing as static methods in ObjC

2 然而,在一个实例中,方法self合理地是对实例的引用。

3 以前,like the usual initialization methodsinitWith...),您会使用id作为返回类型。使用特定的类名会不必要地强制子类覆盖该方法。

答案 1 :(得分:4)

从工厂方法返回的对象应该是自动释放的,这意味着当关联的自动释放池耗尽时,它们将被清除。这意味着除非您copyretain,否则您不拥有返回的对象。以下是工厂方法的示例:

+ (id)myClassWithString:(NSString *)string {
    return [[[MyClass alloc] initWithString:string] autorelease];
}

答案 2 :(得分:2)

这些方法只是返回对象的自动释放版本。

+(MyClass*)class
{
  MyClass* object = [[MyClass alloc] init];
  return [object autorelease];
}

答案 3 :(得分:1)

使用ARC和最新编译器执行此操作的现代方法是:

+ (instancetype) myClassWithString:(NSString *)string {
     return [[MyClass alloc] initWithString:string];
}
  • 无需使用ARC自动发布。
  • instancetype提供了更好的编译时间检查,同时使子类化成为可能。