Вопрос об авторелизном объекте в Objective-C - PullRequest
1 голос
/ 04 сентября 2011

У меня есть переменная экземпляра с именем users, определенная как NSMutableArray.

Я использую эту переменную для заполнения UITableView.

В viewDidLoad Я инициализирую его с помощью:

users = [[MySingleton sharedClass] getUsers];

Это метод getUsers:

- (NSMutableArray *)getUsers
{
    ...   
    NSMutableArray *listArray = [[NSMutableArray alloc] init];

    for (NSDictionary *dict in jsonObject) {
        ...
        [listArray addObject:element];
        ...
    }

    return listArray;
}

Таким образом, все работает нормально. Проблема заключается в том, что я устанавливаю listArray как автоматически выпущенный объект.

NSMutableArray *listArray = [[[NSMutableArray alloc] init] autorelease];

или

return [listArray autorelease];

Иногда приложение вылетает с EXC_BAD_ACCESS.

Почему это? Не правильно установлено autorelease listArray?

Ответы [ 2 ]

3 голосов
/ 04 сентября 2011

Предполагая, что users в users = [[MySingleton sharedClass] getUsers] является переменной экземпляра, вы забываете стать владельцем массива.Если вы хотите претендовать на владение объектом (например, этим массивом), вам нужно отправить его retain, чтобы сообщить, что вы хотите, чтобы он оставался.И когда вы закончите с этим, вам нужно отправить его release, чтобы сказать об этом.Сеттеры обрабатывают это для вас, поэтому, как правило, рекомендуется использовать сеттеры вне методов init и dealloc.Таким образом, предполагая, что у вас есть установщик для users, вы можете сделать одно из следующих действий:

self.users = [[MySingleton sharedClass] getUsers];
/* OR */
users = [[[MySingleton sharedClass] getUsers] retain];

Первый способ обычно лучше, но вы не хотите вызывать установщики в init… или dealloc методы, потому что они могут иметь побочные эффекты, которые там нежелательны.Поскольку здесь нет ни одного из этих методов, вы можете просто использовать первый.

0 голосов
/ 04 сентября 2011

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

...