Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone Objective-C中的嵌套工厂方法_Iphone_Objective C_Xcode_Macos - Fatal编程技术网

Iphone Objective-C中的嵌套工厂方法

Iphone Objective-C中的嵌套工厂方法,iphone,objective-c,xcode,macos,Iphone,Objective C,Xcode,Macos,使用嵌套工厂方法处理内存管理的最佳方法是什么,例如下面的示例 @interface MyClass : NSObject { int _arg; } + (MyClass *) SpecialCase1; + (MyClass *) SpecialCase2; + (MyClass *) myClassWithArg:(int)arg; - (id) initWithArg:(int)arg; @property (nonatomic, assign) int arg; @end

使用嵌套工厂方法处理内存管理的最佳方法是什么,例如下面的示例

@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.]

您认为自动释放池正在刷新的原因是什么

在cocoa touch中不会刷新自动释放池,除非您刷新它,或者控制返回到事件循环

应用程序包将自动关闭 在项目的开头创建一个池 事件循环(或事件循环迭代), 例如鼠标按下事件,以及 在最后释放它,因此您的代码 平时不用担心 他们


为什么您认为自动释放池正在被刷新

在cocoa touch中不会刷新自动释放池,除非您刷新它,或者控制返回到事件循环

应用程序包将自动关闭 在项目的开头创建一个池 事件循环(或事件循环迭代), 例如鼠标按下事件,以及 在最后释放它,因此您的代码 平时不用担心 他们


该错误准确地描述了问题:调用了copyWithZone,但它没有在MyClass中实现。检查指定给它的属性或属性的实现(查看它是否正在复制)。此外,如果MyClass的实例用作NSDictionary的键,则将调用copyWithZone。以下是有关的一些信息。

错误准确地描述了问题:调用了copyWithZone,但它没有在MyClass中实现。检查指定给它的属性或属性的实现(查看它是否正在复制)。此外,如果MyClass的实例用作NSDictionary的键,则将调用copyWithZone。这里有一些关于的信息。

你能发布MyClass的界面吗?(另外,我会为这个类编写一个dealloc方法,如果只是为了完整性的话)。(这是一个简化的例子,改编自我的实际类,它正在爆炸。)你能发布MyClass的接口吗?(另外,我会为这个类编写一个dealloc方法,如果只是为了完整性的话)。(这是一个简化的例子,改编自我的实际班级,它正在爆炸。)“不可以。在您使用任何方法或函数返回之前,您只能指望对象存在。通常,当控件返回到运行循环时,会刷新自动释放池。如果希望对象实例在当前方法之外继续存在,则必须通过调用“retain”来获得它的所有权。然后,您还负责在不再需要实例时“释放”该实例。“是的,这意味着在事件循环调用的方法返回之前,它们不会被刷新。如果要在之后保留某些内容,则必须通过发送保留消息或将其放入带有retain或copy属性的属性来保留它。你这样做的结果是特殊的。我的观点是,自动释放的对象在从SpecialCast返回后仍然处于活动状态。这就是为什么许多人警告不要重新表述内存管理指南。它让人们产生了一些奇怪的想法,比如当一个方法返回时,顶级自动释放池会被神奇地刷新。人们应该阅读《内存管理指南》,并按照它所说的去做。我明白你的意思。因此,从表面上看,上述方法没有明显的缺陷:“如果你想在之后保留某些东西,你必须保留它,可以发送一条保留消息,或者将其放入带有retain或copy属性的属性中。你可以通过SpecialCaseN的结果来保留它。”这正是我对SpecialCaseN的结果所做的(将其放在具有copy属性的属性中),但当[MyClass copyWithZone:]是一个无法识别的选择器时,它就崩溃了“不可以。在您使用任何方法或函数返回之前,您只能指望对象存在。通常,当控件返回到运行循环时,会刷新自动释放池。如果希望对象实例在当前方法之外继续存在,则必须通过调用“retain”来获得它的所有权。然后,您还负责在不再需要实例时“释放”该实例。“是的,这意味着在事件循环调用的方法返回之前,它们不会被刷新。如果要在之后保留某些内容,则必须通过发送保留消息或将其放入带有retain或copy属性的属性来保留它。你这样做的结果是特殊的。我的观点是,自动释放的对象在从SpecialCast返回后仍然处于活动状态。这就是为什么许多人警告不要重新表述内存管理指南。它让人们产生了一些奇怪的想法,比如当一个方法返回时,顶级自动释放池会被神奇地刷新。人们应该阅读《内存管理指南》,并按照它所说的去做。我明白你的意思。因此,从表面上看,上述方法没有明显的缺陷?“如果你想在之后保留某些东西,你必须保留它,要么发送一条保留消息,要么把它放在带有retain或copy属性的属性中。你这样做的结果是SpecialCaseN