(iphone) что происходит с вложенными представлениями при освобождении супервизора?

#iphone #view #subview #retain

#iPhone #Вид #вложенный просмотр #сохранить

Вопрос:

Предположим, что представление (A) имеет вложенные представления. Представление (A) освобождается, потому что его счетчик сохранения равен нулю.

Что происходит с вложенными представлениями view (A)?
Отсоединяются ли они (удаляются из view A) и соответственно уменьшается ли количество их сохранений?

Спасибо

Ответ №1:

Предполагая, что под ‘view’ вы на самом деле имеете в виду ‘экземпляр UIView’:

Представления сохраняют свои вложенные представления, и поэтому, если представление освобождается, его вложенные представления освобождаются, а их количество сохраняемых уменьшается на единицу.

Я не уверен, но предполагаю, что иерархия представлений реализована следующим образом:

 @interface UIView : UIResponder {
  NSArray *_subviews;
}

@property(nonatomic, retain) NSArray *subviews;

@end

@implementation UIView
@synthesize subviews;
- (void)dealloc {
  [subviews release];
  [super dealloc];
}
@end
  

Можно грубо сказать, что NSObject объявляет целое число без знака, которое является счетчиком сохранения, вот так:

 unsigned retainCount;
  

Тогда это были бы реализации -[id<NSObject> retain] и -[id<NSObject> release] :

 - (void)retain {
  retainCount  ;
}

- (void)release {
  retainCount--;
  if (retainCount == 0) {
    [self dealloc];
  }
}
  

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

1. вы имеете в виду, что количество сохранений в подпросмотре уменьшается на единицу и оно освобождается, если количество сохранений достигает нуля?

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

3. Это не совсем так, как вы написали… когда view удаляется, он вызывает [view removeFromSuperview] во всех своих подвидах .. таким образом, они удаляются из своего родительского. Если в этом представлении нет других сохранений, будет вызван dealloc. Иногда бывает удобно перезаписать эту функцию, чтобы очистить материал, который препятствовал бы вызову dealloc из-за сохранения, например, таймеров или тому подобного.

4. @Бастиан, когда ты говоришь «когда представление будет удалено, оно вызовет [view removeFromSuperview] во всех своих вложенных представлениях», ты имеешь в виду «когда представление будет освобождено, оно вызовет …» ?

5. ДА… когда представление освобождается, оно вызывает его во всех вложенных представлениях

Ответ №2:

Все вложенные представления будут освобождены.

Ответ №3:

Если основной вид освобожден, то все дочерние представления внутри него также будут освобождены

Ответ №4:

Функция dealloc супервизора вызовет в subviews’ removedFromSuperview, затем в subviews’ Сообщит SuperView, что «Сообщает представлению, что его superview вот-вот изменится на указанный superview.», в данном случае о том, что он будет освобожден.

Установка точки отладки в подвиде willMoveToSuperview может легко проверить это.

Итак, если подпросмотры являются свойством superview kvo, то здесь самое подходящее место для удаления observer, потому что, если мы сделаем это с subviews dealloc, который будет вызван позже, будет уже слишком поздно. Мы получим исключение типа ‘NSInternalInconsistencyException’, причина: ‘Экземпляр 0x135a9a600 класса UITableView был освобожден, в то время как наблюдатели за значениями ключа все еще были зарегистрированы в нем.