2009-03-24 2 views
4

Какова наилучшая практика сохранения и освобождения объектов, переданных методам класса?Объект сохраняет поведение методов класса Objective-C

Например, если у вас есть "переменная класса" объявлена ​​как так:

static NSString *_myString = nil 

... это правильная вещь, чтобы сделать это:

+ (void)myClassMethod:(NSString *)param { 
    _myString = param; 
} 

... который имеет что вызывающему абоненту необходимо поддерживать ненулевое количество удержания на параме, чтобы оно не было выпущено преждевременно. В качестве альтернативы можно было бы сделать это:

+ (void)myClassMethod:(NSString *)param { 
    [_myString autorelease]; 
    _myString = [param retain]; 
} 

... который имеет недостаток, заключающийся в том, что без соответствующего уровня класса dealloc вызова будет утечка памяти. Или следует избегать такого рода переменных chicanery, возможно, с помощью одноэлементного класса, который управляет временем жизни таких объектов более традиционным способом?

Apple's docs on creating a singleton instance.

Код, с которым я работаю, является очень гладким (но все же новым) проектом Objective Resource (http://www.iphoneonrails.com/).

+0

Вы задаете неправильный вопрос. Вместо того, чтобы спрашивать, как делать глобальные переменные, вы должны обратиться за помощью, чтобы избавиться от ваших глобальных переменных. И да, даже если вы скрываете это за методом класса (или как Singleton), это по-прежнему глобальная переменная. – Sven

ответ

3

Сохраните и освободите, абсолютно. Это не утечка, потому что единственный раз, когда будет вызываться класс dealloc, - это когда программа заканчивается - в это время память будет освобождена в любом случае. Выполнение этого первого способа было бы более сложным и противоречило руководящим принципам управления памятью Cocoa.

Что касается метода класса или синглтона: сами классы вообще не должны иметь много самостоятельной функциональности. Они просто не были разработаны таким образом в Objective-C, как вы можете видеть из-за отсутствия переменных класса. Методы класса обычно должны обрабатывать создание и управление экземплярами и иногда хранить общие свойства или значения по умолчанию для всех экземпляров. Фактическая функциональность класса должна входить в экземпляры. Это соглашение в Objective-C.

(Конечно, нет Objective-C Бог и вы вольны игнорировать конвенции, но это общая мудрость.)

+0

У классов нет метода dealloc, только экземпляры. – dreamlax

+0

Да, для класса нет dealloc, но это не имеет значения.Память, законно удерживаемая глобальным в конце программы, обычно не считается утечкой (все синглтоны работают так). Определенно используйте удержание. –

+0

Я знаю, что классы не имеют методов dealloc. Вот что я имел в виду: даже если у классов были такие методы, их никогда не назовешь. – Chuck

3

Кроме того, в случае NSString или любого класса, который имеет изменяемые варианты (например NSArray или NSDictionary), я настоятельно рекомендую скопировать параметр вместо его сохранения. Если строка, которую передал вам вызывающий, была NSMutableString, ее значение может измениться позже, и оно изменится и в вашем классе. Вероятно, это не то, что вы хотите, так что я бы посоветовал сделать это:

+ (void)myClassMethod:(NSString *)param { 
    [_myString release]; 
    _myString = [param copy]; 
} 

Метод copy делает копию и устанавливает сохранить счетчик на 1, так что вы все сделали, насколько сохранение переменной является обеспокоен. И, в качестве дополнительного бонуса, если вызывающий абонент передает вам NSString, этот класс достаточно умен, чтобы знать, что его значение не может измениться, поэтому оно просто сохраняет себя, чтобы не сделать копию объекта. Насколько это умно?