关于objective c:创建新实例的类方法

Class methods which create new instances

除了标准的[[MyClass alloc] init]模式外,还有一些对象是用静态方法(如MyClass *obj = [MyClass classWithString:@"blabla"]建立的。

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

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


它们是类方法,而不是静态方法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作为返回类型。使用特定的类名不必要地强制子类重写方法。


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

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


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

1
2
3
4
5
+(MyClass*)class
{
  MyClass* object = [[MyClass alloc] init];
  return [object autorelease];
}


用ARC和最新的编译器实现这一点的现代方法是:

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