繁体   English   中英

删除观察者或为NotificationCenter ios找到更好的替代方案

[英]Remove observer or find a better alternative to NotificationCenter ios

我有一些关于NSNotification及其观察者生命周期的问题。

UPD。

我将简化我的应用程序的逻辑,因此它看起来很原始:

ViewController A有一个按钮“ Comment”,还包含一个UIViewB。在这个UIView上,我们还有另一个按钮“ Share”。 如果用户已登录,则每个按钮都会执行应有的操作,否则,它将从NSObject类“ Logistic”(其中逻辑最多的地方)中调用“ login”方法,并显示弹出视图C。 因此,我在C语言中创建了一个postNotificationName,以使按钮在用户登录时进行监听-完成其工作。

例如在viewController A

- (void) comment{
    if (<user_logged_in>){
    //do the magic
                [self removeObserver];
        } else {
            [self removeObserver];
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(comment) name:@"dismiss_popup" object:nil];
            [Logistic login];
        }
}

我对“共享”方法(在视图B中)执行相同的操作,但是例如当我按下按钮“注释”,然后跳过C-登录弹出窗口时,然后按“共享”按钮,进行登录-之后,“共享”和“评论” 将同时开始其操作

我想我应该打电话给removeObserver

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"dismiss_popup" object:nil];

但是,当它仍然存在时,如何在UIView B中进行呢?

问候 。

您可以在物流中修改您的登录方法,如下所示:

功能原型:

+ (void)loginComplete:(void(^)(BOOL success))complete;

功能本身:

+ (void)loginComplete:(void(^)(BOOL success))complete {
//login code
BOOL success = YES;//or no if it was some problems))
complete(success);//replace notification post with this
}

最后是您的viewController A:

- (void) comment{
if (<user_logged_in>){
//do the magic
            [self removeObserver];
    } else {
        [self removeObserver];
        //we don't need Notification center anymore
        [Logistic loginСomplete:^(BOOL success) {
            handle login completion
        }];
    }

}

- (IBAction)commentButton:(id)sender {
    if (!user logged in) {
        [self.logistic loginUserWithCompletion:^(id result){
            if (![result isKindOfClass:[NSError class]]) {
                [self doStuff];
            }
        }];
    } else {
        [self doStuff];
    }

重述您的问题:

  • A是B的父母。
  • A和B呼叫C。
  • A和B听C。
  • 当C发送通知时,A和B都响应,但是您只希望它们之一响应。

我建议让A处理与C的所有通信,因此,如果B需要与C通话,则需要通过A。这是您可以执行的操作:

在UiViewController A中

-(void) viewDidLoad{

 //Adding a notification listener should be done in initialization stage.
 [[NSNotificationCenter defaultCenter] addObserver:self 
                                          selector:@selector(dismissViewC:) 
                                              name:@"dismiss_popup" object:nil];
}
- (void) comment{
    if (<user_logged_in>){
         //proceed with comment
    } else {           
            NSNumber* caller=[NSNumber numberWithInt:COMMENT];
            [Logistic login:caller];
    }
}
-(void) dismissViewC:(NSNotification*) notify{
  (NSNumber*) callerId =[notify object];
   switch(callerId.intValue){
      case COMMENT: //proceed with comment;
      case: SHARE: [self.viewB share];
   }
}
-(void) dealloc {
    // removing an observer should be done in the dealloc stage
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

在UIView B中:

 - (void) share{
        if (<user_logged_in>){
             //proceed with share
        } else {           
                NSNumber* caller=[NSNumber numberWithInt:SHARE];
                [Logistic login:caller];
        }
    }

物流将需要将新的登录参数传递给C,C看起来像这样:

-(void) login:(NSNumber*) caller{
   self.myCaller=caller;
   // proceed with login
}
-(void) dismissMe{
      [[NSNotificationCenter defaultCenter] postNotificationName:@"dismiss_popup"
                                                          object:self.caller];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM