use*_*271 5 objective-c nsnotificationcenter ios
我有下一个代码:
@implementation SplashViewVC
- (void)viewDidLoad
{
[super viewDidLoad];
self.splashView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Default.png"]];
self.activityIndicator.originY = 355.f;
[[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];
[self.activityIndicator stopAnimating];
if (errorCode == ERROR_CODE_NO_CONNECTION) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil];
[alertView show];
} else if (errorCode == 0) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}];
[self downloadData];
}
- (void)downloadData
{
[self.activityIndicator startAnimating];
[[Server sharedServer] getMovieData];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self downloadData];
}
- (void)viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidDisappear:animated];
}
@end
Run Code Online (Sandbox Code Playgroud)
所以我把断点放在viewDidLoad方法的开头,在viewDidDisappear.当我启动首先去的应用程序,viewDidload下载之后就去了viewDidDisappear.
但在我的应用程序中,我再次下载数据和发布notification: NSDownloadComplete.在这个VC中它是有效的,但我后来删除了:
[[NSNotificationCenter defaultCenter] removeObserver:self]
Run Code Online (Sandbox Code Playgroud)
这个VC viewDidLoad在开始时使用一次并且不能再次添加Observer.
怎么了?
编辑
我尝试将addObserver方法放入viewWillAppear或viewWillDisappear- 没有结果.我NSLog(@"addObserver");之前添加
[[NSNotificationCenter defaultCenter] addObserverForName...
Run Code Online (Sandbox Code Playgroud)
在viewDidLoad中
和写
- (void)viewDidDisappear:(BOOL)animated
{
NSLog(@"removeObserver");
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidDisappear:animated];
}
Run Code Online (Sandbox Code Playgroud)
在日志中我看到:
2013-06-10 14:32:05.646 myApp[9390:c07] addObserver
2013-06-10 14:32:06.780 myApp[9390:c07] removeObserver
Run Code Online (Sandbox Code Playgroud)
怎么了?
编辑2 你可以看到必须删除观察者,但它再次在addObserver方法中运行块

Mar*_*n R 24
除了添加/删除观察者呼叫没有正确平衡之外,还有其他答案中提到的另一个问题.
您删除观察者的代码是错误的.对于基于块的观测器,该返回值的addObserver必须被给定为参数removeObserver.所以你应该添加一个属性
@property(nonatomic, strong) id observer;
Run Code Online (Sandbox Code Playgroud)
上课.然后你添加观察者
self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
// ...
}];
Run Code Online (Sandbox Code Playgroud)
并删除它
[[NSNotificationCenter defaultCenter] removeObserver:self.observer];
Run Code Online (Sandbox Code Playgroud)
e1985试图暴露的是你的addObserver和removeObserver电话没有得到适当的平衡.viewDidLoadVC初始化后仅调用一次,但viewDidDisappear每次将视图控制器移出屏幕时调用.
要解决您的问题,您必须平衡您的电话addObserver和removeObserver通话,方法是将它们放入viewDidLoad其中dealloc,或者 - 如同e1985建议的那样 - viewDidAppear:和viewDidDisappear:.
编辑:好了,你的问题来自于事实,你正在使用addObserverForName:object:queue:usingBlock:不注册self为观察者(如addObserver:selector:name:object:如果你传递会做self的第一个参数).
所以在你的情况下,[[NSNotificationCenter defaultCenter] removeObserver:self];什么都不做因为self不是观察者.您应该调用removeObserver:返回值addObserverForName:object:queue:usingBlock:,如文档中所示:
回报价值
一个不透明的对象充当观察者.
所以你的代码看起来应该是这样的:
// header file .h
@interface SplashViewVC : UIViewController
@property (strong, nonatomic) id downloadCompleteObserver;
@end
// implementation file .m
@implementation SplashViewVC
- (void)viewDidLoad
{
[super viewDidLoad];
// [...] snip
self.downloadCompleteObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){
NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];
[self.activityIndicator stopAnimating];
if (errorCode == ERROR_CODE_NO_CONNECTION) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil];
[alertView show];
} else if (errorCode == 0) {
[self dismissViewControllerAnimated:YES completion:nil];
}
}];
[self downloadData];
}
// [...] snip
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self.downloadCompleteObserver];
[super dealloc];
}
@end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4246 次 |
| 最近记录: |