Управление памятью: высвобождение пользовательских объектов в конструкторе - Objective-C - PullRequest
1 голос
/ 03 января 2011

У меня есть метод init, который принимает значения от NSDictionary.Это внутри моего Friend объекта.

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

- (id)initWithValue:(NSString *)value {
    Friend *friend = [[Friend alloc] init];
    friend.friendId = [value valueForKeyPath:@"id"];
    friend.friendName = [value valueForKeyPath:@"name"];

    return friend;
}

Я вызываю метод init ниже, чтобы добавитьFriend объекты в массив friends

for (id value in dataDict) {
    Friend *friend = [[Friend alloc] initWithValue:value];
    [friends addObject:friend];
    [friend release];
}

Затем я делаю следующее в коде:

Friend *friend = (Friend *)[friends objectAtIndex:indexPath.row];

Если I autorelease Friend объект в init Метод, затем я получаю сообщение было отправлено на освобожденный экземпляр, когда я использую приведенный выше код, чтобы получить значение конкретных объектов на основе indexPath.row.

Ответы [ 3 ]

3 голосов
/ 03 января 2011

Пара вещей:

  • метод init не должен вызывать alloc (см. Пример с diwup, чтобы узнать, как правильно сделать init)

  • похоже, что вы пытаетесь создать удобный метод, который создает, инициализирует и возвращает (автоматически освобожденный) объект (аналогично +NSString stringWithFormat: и т. Д.). Вы почти получили его, но вам нужно (а) не называть его «init *» и (б) сделать его методом класса, а не методом экземпляра.

Что-то вроде:

+ (Friend)friendWithValue:(NSString *)value {
    Friend *friend = [[[Friend alloc] init] autorelease];
    friend.friendId = [value valueForKeyPath:@"id"];
    friend.friendName = [value valueForKeyPath:@"name"];

    return friend;
}

Вы бы использовали это как:

[friends addObject:[Friend friendWithValue:value]];
1 голос
/ 03 января 2011

И прямо отвечая на это: Освободите ваши выделенные объекты ТОЛЬКО когда вы закончите с ними.Создать метод и вызвать [выпуск объекта];для всех ваших выделенных объектов.Это позволяет избежать несоответствий при распределении памяти, и этот подход лучше, чем вызов autorelease.

1 голос
/ 03 января 2011

Непосредственно не отвечая на ваш вопрос, но эти строки кода определенно опасны:

- (id)initWithValue:(NSString *)value {
    Friend *friend = [[Friend alloc] init];

Вместо этого вы должны написать так:

- (id)initWithValue:(NSString *)value {
    [super init];
    self.friendId = ...;
    self.friendName = ...;

    return self;
}
...