Class methods which create new instances
除了标准的[[MyClass alloc] init]模式外,还有一些对象是用静态方法(如MyClass *obj = [MyClass classWithString:@"blabla"]建立的。
根据广泛使用的内存管理指南(包括Apple的),您只负责释放alloc的对象。
有人能为我提供这种方法的模板吗?您如何返回分配的对象(可能是[self alloc]; return self;)?你如何确保它会被释放?
- 不仅是+alloc—任何名称以alloc、new、copy、mutableCopy和-retain开头的方法。
它们是类方法,而不是静态方法1。创建自动释放对象的这种特定类型可以称为"工厂方法"(以前也称为"方便构造函数"),并在objc指南中的概念中进行讨论。它们是这样的:
1 2 3
| + (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy {
return [[self alloc] initWithThingummy:theThingummy];
} |
其中Whatsis是您的类,而Thingummy是您的类使用的另一个类。
如果您不使用ARC编译,那么在返回实例之前,约定是对autorelease执行。
针对这些方法,clang引入了instancetype关键字;结合self(在类方法中是类对象itself2),它允许正确的子类行为:该方法生成接收消息的类的实例。3 instancetype允许编译器比EDOCX1执行更严格的类型检查。〔8〕。
从框架的子类中演示这种用法:+[NSString stringWithFormat:]返回NSString实例,而+[NSMutableString stringWithFormat:]返回NSMutableString子类的实例,而不需要NSMutableString显式重写该方法。
正如[Fundamentals][1]Doc所讨论的,这些工厂方法还有其他用途,例如访问一个单例,或者在执行之前对必要的内存分配进行评估(可能,但不太方便,使用标准的alloc/init对)。
<在Java或C++中的1个"静态方法",Objtovi.C中的"类方法"。Objc< /Sub中没有静态方法。
2而在实例方法中,self显然是对实例的引用。
3以前,像通常的初始化方法(initWith...一样,您会使用id作为返回类型。使用特定的类名不必要地强制子类重写方法。
- +1表示返回类型为id,+1表示文档引用,+1表示类方法,+1表示方便的构造函数。
- @谢谢。我很高兴你没有为糟糕的元句法变量找借口。:)
- 喜欢标识符。;-)
- +1.脚注中提到了Clang的instancetype扩展名。
- +1,即使我不得不限制自己编辑元语法变量。
- @乔希:"以前,像通常的初始化方法(initWith…)一样,您将使用id作为返回类型。"当不作为类方法的一部分合并时,ID是否仍用作Style-InitWith的实例方法的返回类型?
- @shinnywhack:instancetpye是一个init...方法的隐式,因此您可以使用id或instancetype。
- 太棒了,乔希,非常感谢。
从工厂方法返回的对象应该是自动释放的,这意味着当关联的自动释放池被清空时,它们将被清除。这意味着您不拥有返回的对象,除非您使用copy或retain。以下是工厂方法的示例:
1 2 3
| + (id)myClassWithString:(NSString *)string {
return [[[MyClass alloc] initWithString:string] autorelease];
} |
- 使用ARC时,使用autorelease是否适用?
- @safx,不,你可以查看由apple制作的笔记:developer.apple.com/library/mac/releasenotes/obiodic/&hellip;
这些方法只是返回对象的自动释放版本。
1 2 3 4 5
| +(MyClass*)class
{
MyClass* object = [[MyClass alloc] init];
return [object autorelease];
} |
- 由于继承的原因,工厂方法通常使用id作为返回类型。
- 我会买的!谢谢!
用ARC和最新的编译器实现这一点的现代方法是:
1 2 3
| + (instancetype) myClassWithString:(NSString *)string {
return [[MyClass alloc] initWithString:string];
} |
- 无需使用ARC自动释放。
- instancetype提供了更好的编译时检查,同时使子类化成为可能。
- 将方法重命名为以单词"new"开头,还是使用ns_returns_retained attribute宏?正如我理解的那样,这样做告诉ARC它接收到一个+1对象,调用方应该拥有该对象的所有权。但这不是必需的,因为默认的自动释放实现将得到相同的结果。