除了标准[[MyClass alloc] init]
模式,一些对象是从静态方法构建的,比如MyClass *obj = [MyClass classWithString:@"blabla"]
根据广泛使用的内存管理指南(包括 Apple 的),您只需负责释放您alloc
.
任何人都可以为我提供此类方法的模板吗?你如何返回分配的对象([self alloc]; return self;
也许)?你如何确保它会被释放?
除了标准[[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
在返回实例之前对其进行处理。
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
它作为返回类型。使用特定的类名会不必要地强制子类覆盖该方法。
从工厂方法返回的对象应该是自动释放的,这意味着当关联的自动释放池耗尽时它们将被清理。这意味着您不拥有返回的对象,除非您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];
}
instancetype
提供更好的编译时间检查,同时使子类化成为可能。