В контроллере представления необходимо ли вызывать removeFromSuperview для подпредставлений во время viewDidUnload? - PullRequest
8 голосов
/ 10 июня 2011

Многие люди говорят, что во время использования метода viewDidUnload контроллера представления необходимо удалить подпредставления, вызвав метод removeFromSuperview. Например, Three20 делает что-то вроде этого:

- (void)viewDidUnload {
  [super viewDidUnload];
  ... snipped ...
  [_tableBannerView removeFromSuperview];
  TT_RELEASE_SAFELY(_tableBannerView);
  [_tableOverlayView removeFromSuperview];
  TT_RELEASE_SAFELY(_tableOverlayView);
  ... snipped ...
}

Я понимаю причину этого убеждения: если вы звоните [self.view addSubview:_aView] в loadView, вам следует позвонить [_aView removeFromSuperview] в viewDidUnload. Дело в том, что это не кажется необходимым. Когда представление контроллера представления освобождается, его метод dealloc автоматически освобождает все его подпредставления. Мой тестовый код показывает, что подпредставления автоматически освобождаются при выпуске их суперпредставления:

@interface TestView : UIView
@end

@implementation TestView
- (id)retain {
    NSLog(@"view retain");
    return [super retain];
}
- (void)release {
    NSLog(@"view release");
    [super release];
}
- (id)init {
    NSLog(@"view init");
    return (self = [super init]);
}
- (void)dealloc {
    NSLog(@"view dealloc");
    [super dealloc];
}
@end

@interface TestViewController : UINavigationController
@end

@implementation TestViewController
- (void)loadView {
    NSLog(@"viewController loadView");
    [super loadView];
    [self.view addSubview:[[TestView new] autorelease]];
}
- (void)viewDidUnload {
    NSLog(@"viewController viewDidUnload");
    [super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"viewDidAppear");
    [super viewDidAppear:animated];
    [self dismissModalViewControllerAnimated:YES];
}
- (void)dealloc {
    NSLog(@"viewController dealloc");
    [super dealloc];
}
@end

Приведенный выше код выдает следующий вывод:

viewController loadView
view init
view retain
view release
viewDidAppear
viewController dealloc
view release
view dealloc

Как вы можете видеть, когда основной вид контроллера представления освобождается, его подпредставления также освобождаются.

Кроме того, библиотека разработчиков iOS [состояния] (http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101-SW4 ): "В случае нехватки памяти стандартным поведением UIViewController является освобождение объекта представления, сохраненного в свойстве представления, если это представление в настоящее время не используется" Кроме того: «Если вы используете объявленное свойство для хранения ссылки на ваше представление, и это свойство использует семантику сохранения, присваивание ему значения nil достаточно для освобождения представления».

Итак, если освобождение представления автоматически освобождает его подпредставление, действительно ли необходимо вызывать removeFromSuperview во время viewDidUnload?

Ответы [ 2 ]

3 голосов
/ 10 июня 2011

Нет, в этом нет необходимости, сделка, как вы правильно сказали, сделает это за вас :) (длинный пост, короткий ответ).

1 голос
/ 16 мая 2012

Я считаю, что это необходимо в моем проекте.Мой viewController имеет основной вид (как и все они), и в этом случае он определяется с использованием xib (не выделяется программно и добавляется как подпредставление).Это представление имеет подпредставления с IBOutlets в контроллере представления.Если в viewDidUnload я просто устанавливаю свойства IBOutlet равными nil (self.mySubView = nil), то dealloc для этого подпредставления не вызывается.Если я сначала удаляю его из его суперпредставления (основного представления), то вызывается dealloc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...