Назначение управления памятью без прямого выделения

#objective-c #memory-management #assign

#objective-c #управление памятью #назначить

Вопрос:

Предположим, что у меня есть UIView viewLoading, объявленный в .h. и я не инициализирую его напрямую (в первом коде).

Первый код.

  UIView *viewLoading2 = [[[UIView alloc] initWithFrame:CGRectMake(75 , 155, 170.0, 170.0)]];
 viewLoading = viewLoading2;
 [viewLoading2 release]
 

Второй код:

 viewLoading = [[[UIView alloc] initWithFrame:CGRectMake(75 , 155, 170.0, 170.0)]];
 

Третий код:

 - (void) viewLoad:(UIView *) viewLoading2
{
  viewLoading = viewLoading2;
  //do i need to retain, alloc, or release something here?

}
 
  1. 2в первом коде нужно ли освобождать загрузку просмотра в dealloc ? И что произойдет, если я не объявлю его свойство?
  2. Во втором коде это имеет тот же эффект, что и в первом коде? (нужно освободить или нет).
  3. Имеет ли третий код тот же эффект, что и первый код? и что мне делать после того, как я это закодирую? (см. Комментарий)
  4. Всегда ли код iPhone должен иметь release для переменной, объявленной в .h? Или только если выделена переменная, объявленная в .h? если, как в первом коде, нужно ли освобождать загрузку просмотра?
  5. в чем разница между

    self.viewloading = viewLoading2;

и

 viewloading = viewLoading2; 
 

Спасибо

Ответ №1:

В первом примере вы выделили объект (один раз) и освободили его (один раз), поэтому вам больше ничего не нужно делать. С другой стороны, загрузка просмотра недопустима, как только вы отправляете релиз в viewLoading2, так что это не очень полезный код.

Во втором случае вы еще не выпустили viewLoading, поэтому в конечном итоге это необходимо сделать.

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

Редактировать:

Я не уверен, что понимаю ваш вопрос 4. Объявление в файле интерфейса (.h) — это просто резервирование места для указателя. Это не объявление объекта, поэтому освобождение не требуется, пока вы фактически не выполните выделение объекта.

self.viewloading = viewLoading2 использует метод установки свойств для выполнения назначения. Если в операторе @property есть «сохранить», то сохранение выполняется как часть этого назначения. `viewloading = viewLoading2″ — это прямое назначение, без сохранения.

Комментарии:

1. Здравствуйте, спасибо за ответ. Итак, в первом коде это недопустимо или нет? потому что вы сказали: «как только вы отправите запрос в viewLoading2, это не очень полезный код». Не сохраняется ли viewLoading2 при загрузке представления? и нужно ли мне делать release для загрузки просмотра? Для 2-го кода я могу просто оставить выпуск для освобождения?

2. Позвольте мне уточнить мой ответ на код 1. Это допустимый синтаксис, и утечки памяти нет, но это бесполезный код, потому что загрузка просмотра указывает на объект, который уже выпущен. Все, что вы сделали в операторе присваивания, это заставили оба указателя указывать на один и тот же объект, который вы затем освободили. Таким образом, они оба указывают на ячейку памяти, в которой больше нет допустимого объекта.

3. Итак, если мой первый код self.viewLoading = viewLoading2, мне нужно правильно освободить viewloading2 (чтобы предотвратить утечку памяти)? Если я не выделяю viewLoading, а затем делаю, как в первом cod (назначить viewLoading = viewLoading2), нужно ли мне освобождать viewLoading в dealloc?

4. Вам ВСЕГДА нужно освободить viewLoading2 (где-то), потому что вы только что выделили его. Если вы это сделаете self.viewLoading = viewLoading2 , то вы можете использовать viewLoading в другом месте и освободить его, когда закончите (возможно, в dealloc). Это базовое (предварительное ARC) управление памятью.

5. Что произойдет, если я не выделяю загрузку представления? нужно ли мне также освобождать его в dealloc? моя загрузка просмотра — это просто self.viewLoading = viewLoading2, моя загрузка просмотра не распределяется. или я должен сначала выделить viewLoading?