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个要点)-