2010-03-21 2 views
0

Каков наилучший способ управления памятью с помощью вложенных заводских методов, например, в следующем примере?Вложенные заводские методы в Objective-C

@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 

Проблема здесь (я думаю), что autorelease бассейн очищается перед методами SpecialCaseN вернуться к своим абонентам [Edit: по-видимому, нет - см комментарии ниже]. Следовательно, конечный вызывающий агент SpecialCaseN не может полагаться на результат, который был сохранен. (Я получаю «[MyClass copyWithZone:]: непризнанный селектор, отправленный экземпляру 0x100110250» при попытке присвоить результат [MyClass SpecialCase1] свойству на другом объекте.)

Причина, по которой требуется использование фабричных методов SpecialCaseN, заключается в том, что в моем фактическом проекте есть несколько параметров, необходимых для инициализации экземпляра, и у меня есть предопределенный список «модельных» экземпляров, которые я хотел бы легко создавать.

Я уверен, что есть лучший подход, чем это.

[Edit:. @interface добавлено в запрос]

+0

Можете ли вы разместить интерфейс для MyClass? (Кроме того, я бы написал метод dealloc для этого класса, хотя бы для полноты) –

+0

Выполнено. (Это упрощенный пример, адаптированный из моего фактического класса, который взрывается.) – StephenT

ответ

1

Ошибка описана точно: copyWithZone вызывается и не реализован в MyClass. Проверьте атрибуты или реализацию назначенного им свойства (см., Если он копирует). Кроме того, copyWithZone будет вызываться, если экземпляр MyClass используется как ключ к NSDictionary. Вот некоторая информация о implementing copyWithZone.

+0

Обычно считается, что copyWithZone: наследуется от NSObject, но это не так. Когда вы создаете подкласс NSObject, вам обычно приходится выполнять его непосредственно. – TechZen

+0

Да, это было. Я действительно предположил, что у меня есть copyWithZone: бесплатно от NSObject. Благодаря! – StephenT

2

Почему вы думаете, что autorelease бассейн смывания?

Пул авторекламы не сбрасывается при контакте с какао, если только вы его не смываете, или управление возвращается обратно в цикл событий.

От iPhone Memory Management Guide

комплекта приложений автоматически создает пул в начале цикла событий (или итерации событий цикла), , такие как мышь вниз события, и выпускает его в конец, поэтому ваш код обычно не должен беспокоиться о них .

+0

От чтения этого ответа, в частности: «Нет. Вы можете рассчитывать только на объект, пока вы не вернетесь от того, какой метод или функция вы используете Как правило, пулы автоопределений сбрасываются, когда управление возвращается обратно в цикл выполнения. Если вы хотите, чтобы экземпляр объекта выдержал за пределами текущего метода, вы должны взять его на себя, позвонив «сохранить». освобождая «экземпляр, когда он вам больше не нужен». http://stackoverflow.com/questions/2017793/question-about-factory-method-object-lifetimes-in-objective-c-cocoa-to-retain-or/2017844#2017844 – StephenT

+0

Да, это означает, что они не сбрасывается до тех пор, пока не вернется метод, вызванный циклом события. Если вы хотите сохранить что-то после этого, вы должны сохранить его, либо отправив сообщение сохранения, либо поместив его в свойство с атрибутом сохранения или копирования. Вы делаете это с помощью SpecialCaseN. Я хочу сказать, что автореализованный объект по-прежнему активен после того, как он возвращается из SpecialCaseN –

+0

Вот почему многие люди предупреждают о перефразировании руководств по управлению памятью.Это дает людям странные идеи, подобные тому, что пул авторесурсов верхнего уровня волшебным образом очищается при возврате метода. Люди должны прочитать Руководство по управлению памятью и перейти к тому, что он говорит. – Chuck

Смежные вопросы