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

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

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

Спасибо


person eugene    schedule 24.04.2011    source источник


Ответы (4)


Предполагая, что под «представлением» вы на самом деле подразумеваете «экземпляр 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];
  }
}
person Community    schedule 24.04.2011
comment
Вы имеете в виду, что количество сохранений подвида уменьшается на единицу, и оно освобождается, если количество сохранений достигает нуля? - person eugene; 24.04.2011
comment
Он освобождается, когда счетчик удержания достигает нуля. Удержание увеличивает количество удержаний, освобождение уменьшает количество удержаний. Всякий раз, когда счетчик сохранения достигает нуля, он будет освобожден, и вы больше не сможете его использовать. - person ; 24.04.2011
comment
Это не совсем так, как вы написали... когда представление будет удалено, оно вызовет [view removeFromSuperview] во всех своих подпредставлениях... поэтому они удалят себя из своего родителя. Если в этом представлении нет других сохранений, будет вызвана команда Dealloc. Иногда бывает удобно перезаписать эту функцию, чтобы убрать то, что может помешать вызову Dealloc из-за сохранения, например, таймеров или чего-то подобного. - person Bastian; 24.04.2011
comment
@Bastian, когда вы говорите, что при удалении представления оно будет вызывать [view removeFromSuperview] во всех своих подпредставлениях, вы имеете в виду, что когда представление освобождается, оно вызывает ...? - person eugene; 25.04.2011
comment
да... когда представление освобождается, оно будет вызывать его во всех подпредставлениях - person Bastian; 25.04.2011
comment
поэтому псевдокод radek должен быть [subviews removeFromSuperview], а не [subviews release] - person eugene; 27.04.2011

Все подвиды будут выпущены.

person Alex Nazarov    schedule 25.04.2011

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

person Radix    schedule 25.04.2011

Dealloc суперпредставления вызовет removedFromSuperview подпредставления, а затем willMoveToSuperview подпредставления, чтобы «Сообщить представлению, что его суперпредставление собирается измениться на указанное суперпредставление.», в этом Дело собирается быть освобожденным.

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

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

person Qiulang    schedule 15.04.2016