Почнемо з retain
і release
; autorelease
насправді це лише окремий випадок, коли ви зрозумієте основні поняття.
У какао кожен об’єкт відстежує, скільки разів на нього посилаються (конкретно, NSObject
базовий клас реалізує це). Зателефонувавши retain
на об’єкт, ви повідомляєте йому, що хочете збільшити його посилання на одиницю. Зателефонувавши release
, ви повідомляєте об'єкт, який ви його відпускаєте, і його кількість посилань зменшується. Якщо після виклику release
кількість посилань зараз дорівнює нулю, пам'ять цього об’єкта звільняється системою.
Основний спосіб цього відрізняється malloc
і free
полягає в тому, що будь-якому даному об'єкту не потрібно турбуватися про збої в інших частинах системи, оскільки ви звільнили пам'ять, яку вони використовували. Якщо припустити, що всі грають і зберігають / випускають згідно з правилами, коли один фрагмент коду зберігається, а потім випускає об'єкт, будь-який інший фрагмент коду, що також посилається на об'єкт, не вплине.
Що іноді може бентежити - це знати обставини, за яких вам слід зателефонувати retain
та release
. Моє загальне правило полягає в тому, що якщо я хочу повісити на об'єкт деякий проміжок часу (наприклад, якщо це змінна члена в класі), то мені потрібно переконатися, що кількість посилань об'єкта знає про мене. Як описано вище, кількість посилань об'єкта збільшується за допомогою виклику retain
. За умовою, він також збільшується (встановлюється дійсно на 1), коли об’єкт створюється методом "init". В будь-якому з цих випадків моя відповідальність викликати release
об'єкт, коли я закінчую його використання. Якщо цього не зробити, відбудеться витік пам'яті.
Приклад створення об'єкта:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
Тепер для autorelease
. Автореліз використовується як зручний (а іноді і необхідний) спосіб сказати системі звільнити цей об’єкт через деякий час. З точки зору сантехніки, коли autorelease
викликається, поточний потік NSAutoreleasePool
повідомляється про виклик. NSAutoreleasePool
Тепер знає , що коли - то він отримує можливість (після поточної ітерації циклу подій), він може зателефонувати release
на об'єкті. З нашого погляду як програмістів, він піклується про release
те, щоб зателефонувати до нас, тому нам не доведеться (а насправді цього не слід).
Важливо відзначити, що (знову ж таки, за умовою) всі методи класу створення об'єктів повертають об'єкт, що вийшов автоматично. Наприклад, у наступному прикладі змінна "s" має кількість відліку 1, але після завершення циклу подій вона буде знищена.
NSString* s = [NSString stringWithString:@"Hello World"];
Якщо ви хочете повісити на цю рядок, вам потрібно буде подзвонити retain
явно, а потім явно, release
коли закінчите.
Розгляньте наступний (дуже надуманий) біт коду, і ви побачите ситуацію, коли autorelease
потрібно:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:@"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
Я усвідомлюю, що все це дещо заплутано - хоча в якийсь момент воно натисне. Ось декілька посилань, які вам допоможуть:
- Вступ Apple в управління пам'яттю.
- Програмування какао для Mac OS X (4-е видання) , Аарон Хіллегас - дуже добре написана книга з великою кількістю чудових прикладів. Він читається як підручник.
- Якщо ви по-справжньому занурюєтесь, ви можете відправитися на ранчо Big Nerd . Це навчальний заклад, яким керує Аарон Хіллегас - автор згаданої вище книги. Я там відвідував курс «Вступ до какао» кілька років тому, і це був чудовий спосіб вчитися.