20

除了标准[[MyClass alloc] init]模式,一些对象是从静态方法构建的,比如MyClass *obj = [MyClass classWithString:@"blabla"]

根据广泛使用的内存管理指南(包括 Apple 的),您只需负责释放您alloc.

任何人都可以为我提供此类方法的模板吗?你如何返回分配的对象([self alloc]; return self;也许)?你如何确保它会被释放?

4

4 回答 4

48

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

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

Whatsis你的班级在哪里,是Thingummy你班级使用的另一个班级。

如果您不使用 ARC 进行编译,则惯例是autorelease在返回实例之前对其进行处理。

Clang 为这些方法引入了关键字instancetype结合self(这是类方法中的类对象本身2)它允许正确的子类行为:该方法生成接收消息的类的实例。3 instancetype允许编译器进行比id.

框架的子类中的这种用法的说明:+[NSString stringWithFormat:]返回一个NSString实例,而+[NSMutableString stringWithFormat:],返回子类的一个实例,而NSMutableString无需NSMutableString显式覆盖该方法。

正如 [ Fundamentals ][1] 文档所讨论的,这些工厂方法还有其他用途,例如访问单例,或在执行之前评估必要的内存分配(可能,但不太方便,使用标准alloc/init对) .


1 Java 或 C++ 中的“静态方法” ,Objective-C 中的“类方法”ObjC 中没有静态方法之类的东西

2而在实例self中,方法显然是对实例的引用。

3以前,与通常的初始化方法( initWith...) 一样,您将使用id它作为返回类型。使用特定的类名会不必要地强制子类覆盖该方法。

于 2011-05-13T06:24:17.463 回答
4

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

+ (id)myClassWithString:(NSString *)string {
    return [[[MyClass alloc] initWithString:string] autorelease];
}
于 2011-05-13T06:23:53.803 回答
2

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

+(MyClass*)class
{
  MyClass* object = [[MyClass alloc] init];
  return [object autorelease];
}
于 2011-05-13T06:24:31.720 回答
1

使用 ARC 和最新编译器的现代方法是:

+ (instancetype) myClassWithString:(NSString *)string {
     return [[MyClass alloc] initWithString:string];
}
  • 无需使用 ARC 自动释放。
  • instancetype提供更好的编译时间检查,同时使子类化成为可能。
于 2013-07-16T12:16:24.773 回答