使用嵌套工厂方法处理内存管理的最佳方法是什么,例如在以下示例中?
@interface MyClass : NSObject {
int _arg;
}
+ (MyClass *) SpecialCase1;
+ (MyClass *) SpecialCase2;
+ (MyClass *) myClassWithArg:(int)arg;
- (id) initWithArg:(int)arg;
@property (nonatomic, assign) int arg;
@end
@implementation MyClass
@synthesize arg = _arg;
+ (MyClass *) SpecialCase1
{
return [MyClass myClassWithArg:1];
}
+ (MyClass *) SpecialCase2
{
return [MyClass myClassWithArg:2];
}
+ (MyClass *) myClassWithArg:(int)arg
{
MyClass *instance = [[[MyClass alloc] initWithArg:arg] autorelease];
return instance;
}
- (id) initWithArg:(int)arg
{
self = [super init];
if (nil != self) {
self.arg = arg;
}
return self;
}
@end
这里的问题(我认为)是在SpecialCaseN方法返回其调用者之前刷新自动释放池[编辑:显然不是 - 请参阅下面的注释]。因此,SpecialCaseN的最终调用者不能依赖于保留的结果。 (我在尝试将[MyClass SpecialCase1]的结果分配给另一个对象的属性时,得到“[MyClass copyWithZone:]:无法识别的选择器发送到实例0x100110250”。)
想要使用SpecialCaseN工厂方法的原因是在我的实际项目中,初始化实例需要多个参数,我有一个预定义的“模型”实例列表,我希望能够创建容易。
我确信有比这更好的方法。
[编辑:每个请求添加@interface。]
答案 0 :(得分:2)
为什么你认为自动释放池正在被刷新?
自动释放池不会在cocoa-touch中刷新,除非您将其刷新,或者将控制权返回给事件循环。
来自iPhone Memory Management Guide
自动应用套件 在一个开头创建一个池 事件循环(或事件循环迭代), 例如鼠标按下事件,和 最后发布它,所以你的代码 通常不必担心 它们。
答案 1 :(得分:1)
错误完全描述了问题:调用copyWithZone并且它未在MyClass中实现。查看它所分配的属性的属性或实现(看它是否正在复制)。此外,如果将MyClass的实例用作NSDictionary的键,则将调用copyWithZone。以下是implementing copyWithZone的一些信息。