ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C Часть 1

Управление памятью (Memory management)

В некоторых статьях я говорил, что напишу как правильно работать с память. В этой статье именно этим я и хочу заняться. Ваша программа не является единственной программой на устройстве (iPhone/iPad), и оперативно запоминающее устройство (ОЗУ или память) является ценным ресурсом. Если вашей программе больше не нужна часть памяти, вы должны освободить ее (память), отдать в распоряжение системы. Когда ваша мама сказала вам, что вы должны быть вежливы и жить в гармонии с обществом, она учила вас как программировать! Даже если ваша программа единственная сейчас работает, заполнение памяти может привести к тому, что ваша программа аварийно завершиться.

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

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

Для того, чтобы помочь вам освобождать память из под объектов, которые вам больше не нужны, Objective-C создает у каждого объекта счетчик, который называется «число ссылок на объект» (retain count). Когда вы сохраняете ссылку на объект в программе, вы должны позволить объекту знать об этом путем увеличения счетчика на единицу. Когда вы убираете ссылку на объект, вы должны, соответственно, уменьшить значение счетчика. Когда значение счетчика становиться равным нулю, объект «понимает», что на него ссылок больше нет и он может быть удален из памяти.

Например, предположим, что ваше приложение — это музыкальный плеер и у вас есть объекты, представляющие собой песни и плейлисты. Предположим, что на один объект «песня» ссылается три объекта «плейлист». Если на него (объект «песня») больше никакой другой объект не ссылается, ваша песня имеет число ссылающихся объектов равное трем. Объект знает сколько раз на него ссылаются благодаря счетчику.

Для того, чтобы увеличить счетчик ссылающихся объектов, вам нужно всего лишь послать сообщение:

<code data-result="[object Object]">[anObject retain];</code>

Чтобы уменьшить значение, нужно послать сообщение об освобождении объекта:

<code data-result="[object Object]">[anObject release];</code>

Также Objective-C предлагает механизм, называемый «Autorelease pool», который позволяет посылать отложенное сообщение об освобождении объекта. Т.е. это сообщение будет послано не в момент отправки, а через некоторое время. Чтобы использовать данную функциональность, вы должны зарегистрировать объект в пуле автоматически освобождаемых объектов (Autorelease pool), послав сообщение следующим образом:

<code data-result="[object Object]">[anObject autorelease];</code>

То есть, ваша работа по управлению памятью сводится к простому правилу. Если вы создается объект используя методы alloccopy,mutableCopynew или посылаете объекту команду retain, не забудьте отправить ему release или autorelease сообщение в конце функции. Если вы создаете объект другими способами, то не делайте ничего.

Вы не должны вручную уничтожать autoreleased объекты, это будет ошибкой.

Давайте вернемся к коду, который мы уже разбирали в прошлых статьях:

<code data-result="[object Object]">//a1 будет уделена автоматически
NSMutableArray *a1 = [NSMutableArray arrayWithCapacity:10];

//для a2 мы должны вручную вызвать метод release
NSMutableArray *a2 = [[NSMutableArray alloc] initWithCapacity:10];
[a2 release];

//метод инициализации a3 идентичен методу a1
NSMutableArray *a3 = [[[NSMutableArray alloc] initWithCapacity:10] autorelease];</code>

Чтобы узнать какие методы возвращают нам autoreleased объекты откройте список методов инициализации выбранного класса. Если вы читали статью Источники информации (поиск методов), то для вас это не составит труда. Теперь найдите методы инициализации. И если вы будете внимательны — то заметите, что некоторые методы начинаются со знака плюс, а некоторые — минус. Так вот те методы, которые отмечены плюсом являются методами класса, как раз они и  создают авторелизнутые объекты (им не нужено посылать команду release или autorelease). А методы, которые начинаются со знака минус — являются методами экземпляра объекта (перед их вызовом нам необходимо создать объект,  а потом вызвать его метод). Созданным объектам таким образом, после их использования следует посылать release или autorelease.

На последок хотелось бы уточнить один момент, о котором не все знают (забывают или игнорируют). Следующие два метода идентичны:

<code data-result="[object Object]">NSString *string1 = [[NSString alloc] init];
NSString *string1 = [NSString new];</code>

Поэтому, если вы хотите, чтобы ваш код выглядел изящно и компактно — пишите по-меньше кода.

Дальнейшее обсуждение и рассмотрение возможных ошибок по работе с памятью проходит в этой ветке форума.

Comments are closed.