除了标准的[[MyClass alloc] init]
模式外,一些对象是从静态方法构建的,例如MyClass *obj = [MyClass classWithString:@"blabla"]
根据广泛的内存管理指南(包括Apple的),您只负责释放alloc
的对象。
任何人都可以为我提供此类方法的模板吗?你如何返回分配的对象(也许是[self alloc]; return self;
)?你如何确保它会被释放?
它们是类方法,而不是静态方法1。创建自动发布对象的这种特定类型可以称为"工厂方法"(以前也称为"方便构造函数"),它们在 ObjC 指南中的概念中进行了讨论。他们是这样的:
+ (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy {
return [[self alloc] initWithThingummy:theThingummy];
}
其中Whatsis
是你的类,Thingummy
是你的类使用的另一个类。
如果不使用 ARC 进行编译,约定是在返回实例之前autorelease
实例。
instancetype
关键字是由Clang为这些类型的方法引入的;结合self
(类方法中的类对象本身2),它允许正确的子类行为:该方法生成接收消息的类的实例。3 instancetype
允许编译器执行比id
更严格的类型检查。
类中这种用法的说明:+[NSString stringWithFormat:]
返回一个NSString
实例,而+[NSMutableString stringWithFormat:]
返回子类NSMutableString
的实例,而不需要NSMutableString
显式覆盖该方法。
正如[Fundamentals][1]文档所讨论的,这些工厂方法还有其他用途,例如访问单例,或在执行之前评估必要的内存分配(可能,但不太方便,使用标准alloc
/init
对)。
1Java或C++中的"静态方法",Objective-C中的"类方法"。ObjC 中没有静态方法这样的东西
2而在实例中,方法self
显然是对实例的引用。
3以前,与通常的初始化方法(initWith...
)一样,您将使用id
作为返回类型。使用特定的类名会不必要地强制子类重写该方法。
从工厂方法返回的对象应自动释放,这意味着当关联的自动释放池耗尽时,将清理这些对象。这意味着,除非您copy
或retain
返回的对象,否则您不拥有返回的对象。下面是工厂方法的示例:
+ (id)myClassWithString:(NSString *)string {
return [[[MyClass alloc] initWithString:string] autorelease];
}
这些方法只是返回对象的自动发布版本。
+(MyClass*)class
{
MyClass* object = [[MyClass alloc] init];
return [object autorelease];
}
使用 ARC 和最新的编译器执行此操作的现代方法是:
+ (instancetype) myClassWithString:(NSString *)string {
return [[MyClass alloc] initWithString:string];
}
- 无需使用 ARC 自动发布。
-
instancetype
提供了更好的编译时检查,同时使子类化成为可能。