Objective c 使用PoptorootViewController时接收NSNotification时出现问题
我有一个Objective c 使用PoptorootViewController时接收NSNotification时出现问题,objective-c,cocoa-touch,nsnotification,Objective C,Cocoa Touch,Nsnotification,我有一个UIViewController,用户点击一个按钮,然后进入另一个UIViewController进行一些图像处理。一旦图像被处理,我需要一个NSNotification 我的突出问题是,当用户完成图像裁剪时,我没有在第一个UIViewController中收到NSNotification。。。我涵盖了所有理由,并将通知处理方法放入viewDidLoad,viewwillbeen,viewwillbeen 我不明白为什么我没有收到通知?这应该很直截了当 如果我注释掉[[NSNotific
UIViewController
,用户点击一个按钮,然后进入另一个UIViewController
进行一些图像处理。一旦图像被处理,我需要一个NSNotification
我的突出问题是,当用户完成图像裁剪时,我没有在第一个UIViewController
中收到NSNotification
。。。我涵盖了所有理由,并将通知处理方法放入viewDidLoad
,viewwillbeen
,viewwillbeen
我不明白为什么我没有收到通知?这应该很直截了当
如果我注释掉[[NSNotificationCenter defaultCenter]removeObserver:self]代码>从<代码>视图消失
它可以工作。。。。但从理论上讲。。。如果我正在重新设置通知处理程序,那么应该在3种可用方法中的任何一种中再次调用它们
第一个UIViewController和NSNotification接收器
- (void) addNewPictureFromLibrary {
[self.view endEditing:YES];
imageCroppingViewController* popupController = [self.storyboard instantiateViewControllerWithIdentifier:@"imageCroppingView2"];
[self.navigationController pushViewController:popupController animated:YES];
}
- (void) viewDidDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void) viewDidLoad {
[self notifications];
}
- (void) viewWillAppear:(BOOL)animated {
[self notifications];
}
- (void) viewDidAppear:(BOOL)animated {
[self notifications];
}
- (void) notifications {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(imageCroppingView:)
name:@"imageCroppingView"
object:nil];
}
- (void) imageCroppingView:(NSNotification *) notification {
NSLog(@"imageCroppingView IN HERE");
}
- (void) finishCropping {
float zoomScale = 1.0 / [scrollView zoomScale];
CGRect visibleRect;
visibleRect.origin.x = scrollView.contentOffset.x * zoomScale;
visibleRect.origin.y = scrollView.contentOffset.y * zoomScale;
visibleRect.size.width = scrollView.bounds.size.width * zoomScale;
visibleRect.size.height = scrollView.bounds.size.height * zoomScale;
UIImage *cropped = imageFromView(imageView.image, &visibleRect);
NSDictionary *dictionary = @{@"image":cropped};
self.navigationController.navigationBar.hidden = NO;
[self.navigationController popToRootViewControllerAnimated:TRUE];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"imageCroppingView"
object:nil
userInfo:dictionary];
}
发送方UIViewController
- (void) addNewPictureFromLibrary {
[self.view endEditing:YES];
imageCroppingViewController* popupController = [self.storyboard instantiateViewControllerWithIdentifier:@"imageCroppingView2"];
[self.navigationController pushViewController:popupController animated:YES];
}
- (void) viewDidDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void) viewDidLoad {
[self notifications];
}
- (void) viewWillAppear:(BOOL)animated {
[self notifications];
}
- (void) viewDidAppear:(BOOL)animated {
[self notifications];
}
- (void) notifications {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(imageCroppingView:)
name:@"imageCroppingView"
object:nil];
}
- (void) imageCroppingView:(NSNotification *) notification {
NSLog(@"imageCroppingView IN HERE");
}
- (void) finishCropping {
float zoomScale = 1.0 / [scrollView zoomScale];
CGRect visibleRect;
visibleRect.origin.x = scrollView.contentOffset.x * zoomScale;
visibleRect.origin.y = scrollView.contentOffset.y * zoomScale;
visibleRect.size.width = scrollView.bounds.size.width * zoomScale;
visibleRect.size.height = scrollView.bounds.size.height * zoomScale;
UIImage *cropped = imageFromView(imageView.image, &visibleRect);
NSDictionary *dictionary = @{@"image":cropped};
self.navigationController.navigationBar.hidden = NO;
[self.navigationController popToRootViewControllerAnimated:TRUE];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"imageCroppingView"
object:nil
userInfo:dictionary];
}
这是因为您正在从视图中的
NSNotificationCenter
中删除self
。
当加载另一个视图时,viewDidEnglish
会自动调用到现有的视图控制器上,因此它会自动为所有通知重新注册,因为第一个UIViewController中有此代码-
- (void) viewDidDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
viewdidegale
是在加载imageCroppingViewController之前调用的最后一个方法,此后您将永远不会注册
如果要有选择地取消某些通知的注册,请使用NSNotificationCenter
name方法调用removeObserver
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"NotificationNameYouDontWantToListenAnyLonger" object:nil];
请注意,多次调用addObserver
获取通知并不意味着您注册了那么多次。对象在每个通知的通知中心中只有一个条目(粗略地说,每个通知名称都有唯一的对象)
我希望这能澄清问题,让你们找到解决办法。如果有任何问题,请告诉我。是的,我知道我正在移除
viewdidegase
中的观察者。但我需要删除Observer,这是注销它们的最佳位置。。。问题是,我还在viewwillbeen
注册观察家,该观察家在poptrootviewcontrolleranimated
之后被调用,但时间不够快,无法获得通过的nsnofication。您只需在viewDidLoad
中注册观察家,然后移除观察家(取消注册)在视图控制器的dealloc
方法中-这意味着只要通知处于活动状态(即使视图不可见),控制器就会侦听通知。另一个选项是在视图中注册和取消注册将分别出现
和ViewDidInviser
-这意味着视图控制器仅在可见时(在屏幕上)才会侦听通知。您没有dealloc方法。类仍然有dealloc(即使是自动引用计数后)但是现在不能对任何对象调用dealloc。它通常仅用于此类清理工作。我建议您阅读此链接中的“ARC强制执行新规则”(前3个要点)-