Когда и когда не выделять память для объектов - PullRequest
0 голосов
/ 23 марта 2012
NSArray *array = [dictionary objectForKey:@"field"];

и

NSArray *array = [[NSArray alloc] initWithArray:[dictionary objectForKey:@"field"]];

Я часто вижу оба вида подходов в объективном C-коде. Когда попытался понять, я обнаружил, что оба они используются в аналогичной ситуации, что противоречит. Мне не ясно, когда мне следует использовать первый подход, а когда второй? Есть идеи?

Подробные объяснения и полезные ссылки приветствуются мамами.

Ответы [ 2 ]

1 голос
/ 23 марта 2012

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

Но, если вы спрашиваете разницу между получениемОбъекты по методам alloc или удобство.([NSString alloc] init vs [NSString stringWith ...), по соглашению, вам принадлежит все, что вы вызываете alloc, new copy или mutableCopy.Все, что вы называете, но не те, автоматически выпущено.

См. Руководство по памяти здесь .В частности, обратите внимание на правила .

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

Например:

// my object doesn't need that formatted string - create the autoreleased version of it.
- (NSString) description {
    return [NSString stringWithFormat:@"%@ : %d", _title, _id]; 
}

// my object stuffed it away in an iVar - I need the retained version of it.  release in dealloc
- (void) prepare {
    _myVal = [[NSString alloc] initWithFormat:"string I need for %d", _id];
}

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

Во втором примере я форматирую строку и присваиваю ее переменной iVar, которую мне нужно удерживать на протяжении жизни моего класса, поэтому я вызываю alloc, которая сохранит ее.Я владею им и выпускаю его в конце концов.Теперь я мог бы использовать первую версию здесь и просто вызвать на ней также retain.

0 голосов
/ 23 марта 2012

У вас есть фундаментальное неправильное понимание распределения по сравнению с методами экземпляра.

Первый пример, метод NSDictionary -objectForKey, возвращает id, а не экземпляр NSDictionary, поэтому он не выделяет и не инициализирует переменную.

Второй, однако, является классической частью сохраненияцикл retain-release.

Два метода в основном равны (если предположить, что массив выделен, но пуст в первом, и ноль во втором), и оба получают владение массивомобъект.Я бы пошел со вторым, поскольку он гарантирует ссылку, и он короче.

Я думаю, что вы путаете это с новыми и удобными методами.Вспомогательные методы (например, NSNumber + numberWithInt :, NSString's + stringWithFormat: и NSMutableArray's + array) возвращают экземпляр класса автоматического выпуска (обычно).New заменяет alloc и init одним словом.

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