除标准[[MyClass alloc] init]
模式外,某些对象是使用静态方法构建的,如MyClass *obj = [MyClass classWithString:@"blabla"]
根据广泛的内存管理指南(包括Apple),您只负责发布alloc
的对象。
有人能为我提供这种方法的模板吗?你如何返回分配的对象(也许是[self alloc]; return self;
)?你如何确保它会被释放?
答案 0 :(得分:48)
它们是类方法,而不是静态方法 1 。创建自动释放对象的这种特定类型可以称为“工厂方法”(以前也称为“便利构造函数”),它们在the Concepts in ObjC Guide中讨论。他们是这样的:
+ (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy {
return [[self alloc] initWithThingummy:theThingummy];
}
Whatsis
是您的班级,Thingummy
是您班级使用的另一个班级。
如果您没有使用ARC进行编译,那么在返回之前,约定是autorelease
实例。
Clang为这些方法引入了instancetype
keyword;结合self
(在类方法中是class object本身 2 )它允许正确的子类行为:该方法生成接收消息的类的实例。 sup> 3 instancetype
允许编译器执行比id
更严格的类型检查。
来自框架的子类中此用法的说明:+[NSString stringWithFormat:]
返回NSString
实例,而+[NSMutableString stringWithFormat:]
返回子类NSMutableString
的实例,而不NSMutableString
1}}需要显式覆盖方法。
正如[基础] [1] doc所讨论的那样,这些工厂方法还有其他用途,例如访问单例,或者在执行之前评估必要的内存分配(可能,但是方便,标准alloc
/ init
对。
1 Java或C ++中的“静态方法”,Objective-C中的"class methods"。 There's no such thing as static methods in ObjC 子>
2 然而,在一个实例中,方法self
合理地是对实例的引用。
3 以前,like the usual initialization methods(initWith...
),您会使用id
作为返回类型。使用特定的类名会不必要地强制子类覆盖该方法。
答案 1 :(得分:4)
从工厂方法返回的对象应该是自动释放的,这意味着当关联的自动释放池耗尽时,它们将被清除。这意味着除非您copy
或retain
,否则您不拥有返回的对象。以下是工厂方法的示例:
+ (id)myClassWithString:(NSString *)string {
return [[[MyClass alloc] initWithString:string] autorelease];
}
答案 2 :(得分:2)
这些方法只是返回对象的自动释放版本。
+(MyClass*)class
{
MyClass* object = [[MyClass alloc] init];
return [object autorelease];
}
答案 3 :(得分:1)
使用ARC和最新编译器执行此操作的现代方法是:
+ (instancetype) myClassWithString:(NSString *)string {
return [[MyClass alloc] initWithString:string];
}
instancetype
提供了更好的编译时间检查,同时使子类化成为可能。