Статьи

Основы iPhone: управление памятью

Одним из главных источников путаницы для новых разработчиков iPhone является управление памятью. Если вы привыкли использовать удобные языки сценариев для сборки мусора, вам может быть интересно, почему управление памятью даже необходимо. Хотя Cocoa поддерживает сборку мусора, для телефонной платформы это было слишком дорого. Поэтому для разработчиков важно знать, как правильно распределять и освобождать объекты. Следуя некоторым простым рекомендациям, вы можете избежать большинства проблем управления памятью. 1. Если вы выделяете объект, вы должны освободить его, как только закончите. Когда вы выделяете объект, вы «владеете» этим объектом и несете ответственность за его освобождение по окончании использования:

  Widget * widget = [[Widget alloc] init]; // Сделать что-то с помощью widget ... [widget release]; 

Вы можете думать об release как о том, что вы отказываетесь от владения этим объектом , а не уничтожаете его . За кулисами Cocoa выполняет подсчет ссылок, чтобы отслеживать владельца. Если никто не претендует на право собственности, объект будет уничтожен, а память, которую он занимал, будет возвращена. 2. Если вы не разместили объект напрямую, вы не должны освобождать его. Как только вы получаете навык release , возникает соблазн выпустить объекты, когда вы не должны. Типичным примером является использование фабричных методов:

  NSString * label = [NSString stringWithFormat: @ "Title:% @", widget.title]; // Сделать что-то с label [label release] // К сожалению, неверно. 

В этом примере был создан новый строковый объект, но мы не распределили его и не владеем им. Поэтому мы не должны вызывать release здесь — это может вызвать перевыпуск, который может привести к сбою вашего приложения.

совет: как этот объект выпущен?

За кулисами NSString вызывал autorelease для строки перед возвратом, что мы рассмотрим autorelease .

3. Если вам нужен объект, вы должны retain его (и release когда закончите). Это правило применяется, когда мы получаем объект, созданный кем-то другим. Например, рассмотрим метод установки:

  - (void) setName: (NSString *) newName; {[newName retain];  // нам нужен новый строковый объект.  [название релиза];  // нам больше не нужна старая строка  name = newName;} 

retain сигналы о том, что мы заявляем о праве собственности на объект; он не будет уничтожен, когда первоначальный владелец выпустит его. Но теперь, когда мы владеем объектом, мы должны освободить его, когда он нам больше не нужен. Под капотом retain и release обновите счетчик ссылок объекта, увеличивая и уменьшая соответственно. Следование этому шаблону значительно упрощает управление памятью. При передаче объекта в метод мы можем предположить, что он будет сохранен (при необходимости), и мы можем сразу же освободить его:

  UIButton * button = [[UIButton alloc] initWithFrame: myFrame]; [self.view addSubview: button] // Здесь мы можем предположить, что представление // сохранило кнопку, [button release] // мы можем безопасно ее отпустить. 

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

  NSMutableArray * widgetList = [[NSMutableArray alloc] init]; // ... Widget * widget = [[Widget alloc] init]; [widgetList addObject: widget];  // сохраняет виджет [widget release];  // мы можем освободить виджет // ... [widgetList release] // объекты в коллекции будут освобождены. 

4. Если вы создаете объект и не сохраняете контроль над ним, используйте autorelease релиз. Скажем, вы хотите создать свой собственный фабричный метод для Widget. Здесь мы создаем новый объект Widget и возвращаем его из метода класса:

  + (Widget *) createBetterWidget {Widget * widget = [[Widget alloc] init];  [widget setAwesome: 11];  return [autorelease виджета];} 

Мы по-прежнему несем ответственность за освобождение объекта, поэтому мы вызываем autorelease перед его возвратом. autorelease сигнализирует, что объект должен быть освобожден «в конце концов». Объект добавляется в пул, который очищается в конце цикла выполнения приложения. Может показаться заманчивым автоматическое освобождение всего в качестве решения для управления памятью, однако это не рекомендуется, так как вашему приложению может не хватить памяти до того, как пул авто-выпусков будет исчерпан. Наилучшим подходом является простой и недвусмысленный подход к распределению и освобождению объектов. Следуйте этим простым правилам, и вы будете на пути к созданию безошибочного и эффективного кода. Для углубленного освещения этих тем руководство по программированию для управления памятью Apple является важным чтением для новых разработчиков. Автор изображения : Dezeen