2

我有一个简单的 viewController 想听UIKeyboardWillHideNotification。因此我有以下代码:

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillBeHidden)
                                                 name:UIKeyboardWillHideNotification object:nil];
}

- (void) keyboardWillBeHidden
{
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
}

我正在尝试决定何时将 viewController 作为通知中心观察者删除。我只需要知道UIKeyboardWillHideNotification视图控制器何时出现在屏幕上,因此我正在考虑添加以下内容:

- (void) viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

这足够了吗?当 viewController 仍在屏幕上时,是否有机会viewDidUnload或将被调用?dealloc 请注意,我使用的是非常基本UINavigationController的应用程序流程。

4

2 回答 2

5

Registering the notification in viewWillAppear and unregistering it in viewWillDisappear seems to be a clean and symmetric solution to me.

Note that viewWillAppear can be called multiple times before dealloc (e.g. if another view controller is pushed onto your VC, or if you switch between tab bar controllers.) If you register the notification in viewWillAppear and unregister it only in dealloc then you will get duplicate registrations (compare Warning for iOS/iPhone users about duplicate NSNotification observations) and the registered selector is called multiple times for a single notification event.

I actually prefer the block-based observer registration method

addObserverForName:object:queue:usingBlock:

which returns an opaque object which is used for removing the observer again. Storing this return value into an instance variable of your view controller helps to keep track if the observer is already registered or not, and therefore helps to avoid duplicate registrations.

于 2013-03-30T19:20:38.373 回答
0

To answer your direct question, dealloc will never be called while your view is still on screen unless you directly call it which you shouldn't be.

dealloc will only be called when there are no strong pointers remaining that point to your viewController.

As Anoop Vaidya suggests, it is totally doable to put removeObserver in dealloc and be confident that dealloc won't get called while your viewController is on screen, and if it does... well you have much bigger problems than removing an observer

Edit: Since I can't actually reply to comments yet, when your viewController is off screen it is actually deallocated. It is then re-instantiated when it is called back on screen.

Edit: I'm wrong

于 2013-03-30T18:21:22.390 回答