Цель C: Правильный способ инициализации NSArray, который является @property - PullRequest
8 голосов
/ 08 апреля 2011

У меня есть свойство в моем классе, которое является NSArray. Я сохраняю собственность.

Мой вопрос: как правильно добавить объекты в этот массив без утечки и слишком большого количества сохраняемых данных?

Вот что я использую:

.h:

NSArray *foodLocations;

@property (nonatomic, retain) NSArray *foodLocations;

// Я проверяю, чтобы синтезировать и освободить свойство в моем dealloc.

.m

- (void)viewDidLoad {
    [super viewDidLoad];

    NSArray *tempFood = [[NSArray alloc] initWithArray:[self returnOtherArray]];
    self.foodLocations = tempFood;
    [tempFood release];

}

Это правильный способ сделать это?

Ответы [ 5 ]

8 голосов
/ 08 апреля 2011

Да, это правильно, и мой предпочтительный способ сделать это, так как это делает код более читабельным.

Вы, по сути, выделяете временный массив, а затем присваиваете его свойству с атрибутом retain, так что можно безопасно освободить его, поскольку ваше свойство теперь «владеет» им. Просто помните, что вам все еще нужно выпустить его по вашему dealloc методу.

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

4 голосов
/ 08 апреля 2011

в этом случае вы обычно хотите объявить копию свойства.

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

копирование в этой форме (сборнике) мелкое. объекты в массиве не копируются, только выделение массива.

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

Ваша программа упрощается до объявления:

// note: copy, not retain. honor this if you implement the accessors.
@property (nonatomic, copy) NSArray * foodLocations;

и затем установщик:

self.foodLocations = [self returnOtherArray];

Конечно, вы все равно должны правильно инициализировать, освобождать и обрабатывать безопасность потоков.

удачи

3 голосов
/ 08 апреля 2011

Или:

@synthesize foodLocations=_foodLocations;

затем в коде

_foodLocations = [[NSArray alloc] initWithArray:someOtherArray];

Это позволяет избежать автоматического выпуска, требуемого

self.foodLocations = [[[NSArray alloc] initWithArray:someOtherArray] autorelease];
3 голосов
/ 08 апреля 2011

Это выглядит хорошо. Вам на самом деле не нужна переменная tempFood, вы можете просто сделать:

self.foodLocations = [[NSArray alloc] initWithArray:[self returnOtherArray]];
[self.foodLocations release];

или

self.foodLocations = [[[NSArray alloc] initWithArray:[self returnOtherArray]] autorelease];
2 голосов
/ 08 апреля 2011

Да, это правильно.Также хорошо иметь в виду, что @synthesize, по сути, делает для вас.Синтезированный (и сохраненный) сеттер функционально эквивалентен следующему коду:

- (void)setVar:(id)_var {
    [_var retain];
    [var release];
    var = _var;
    [var retain];
    [_var release];
}

Таким образом, в основном, каждый раз, когда вы вызываете self.var = foo, он освобождает ранее сохраненное значение и сохраняет новое.Вы обрабатываете подсчет ссылок в своем коде, а установщик обрабатывает его самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...