Лучшая практика для назначения новых объектов для сохраненных свойств? - PullRequest
1 голос
/ 12 ноября 2009

Я использую Core Data для своего приложения для iPhone. Мои атрибуты установлены с сохраненными свойствами.

Например, атрибут «число» в сущности «Вещь»:

#import <CoreData/CoreData.h>

@interface Thing :  NSManagedObject  
{
}
@property (nonatomic, retain) NSNumber * number;
@end

@implementation Thing 
@dynamic number;
@end

При работе с объектами Thing в моем коде я устанавливал свойство числа следующим образом:

thing.number = [[NSNumber alloc] initWithInteger:1];

Однако, это создает утечку памяти (новый объект NSNumber имеет счет сохранения, который на один больше, чем требуется из-за сохранения свойства alloc плюс).

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

  1. Я знаю, что этот шаблон работает (и он уже обсуждался в нескольких сообщениях SO):

    NSNumber *num = [[NSNumber alloc] initWithInteger:1];
    thing.number = num;
    [num release];
    

    Этот шаблон очень ясен, но я не в восторге от трех строк или временной переменной.

  2. Я думаю, что это будет работать также (но я не заметил это ни на одном SO сообщениях):

     thing.number = [[NSNumber alloc] initWithInteger:1];
     [thing.number release];
    

    Этот шаблон менее понятен, но требует только две строки и не использует временную переменную.

Вопрос
Существуют ли другие шаблоны для назначения новых объектов сохраненным свойствам (без использования пулов автоматического выпуска)? Какова лучшая практика здесь?

Ответы [ 4 ]

3 голосов
/ 12 ноября 2009

Помимо использования пулов автоиздания, это единственные, которые я, например, видел. Я бы не стал слишком опасаться авто-релиза. Они работают просто отлично, и в этом случае вы, вероятно, не увидите никакой разницы в производительности.

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

2 голосов
/ 12 ноября 2009

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

Для записи, второй шаблон тоже должен нормально работать.

1 голос
/ 12 ноября 2009

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

thing.number = [NSNumber numberWithInt: 1];

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

В любом случае, если это не применимо, поскольку у вас нет конструкторов, возвращающих автоматически выпущенные объекты, ваш шаблон 1 определенно верен.

Вместо этого шаблон 2 кажется мне неправильным по следующей причине: сначала вы присваиваете NSNumber своей собственности, а затем освобождаете свою собственность. Однако вам необходимо освободить выделенный вами NSNumber, а не тот, который был сохранен вашей собственностью (вы сделаете это позже, еще раз, когда закончите со своей собственностью). Чистым эффектом шаблона 2 должна быть утечка памяти (выделенный номер NSN не освобождается) и ваше свойство не содержит номер NSN (потому что вы сначала сохранили его, а затем освободили).

1 голос
/ 12 ноября 2009

Пулы автоматического выпуска не должны использовать значительно больше памяти, если вы не создаете много объектов в узком цикле.

Я полагаю, вы можете использовать две или три строки кода, которые вам нужно написать, или просто использовать пулы авто-релиза.

Лично я бы определенно использовал пулы автоматического выпуска, если не столкнусь с конкретными проблемами производительности или памяти.

...