Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/112.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如果通知多个观察者,则只调用一个_Ios_Nsnotificationcenter_Nsnotification - Fatal编程技术网

Ios 如果通知多个观察者,则只调用一个

Ios 如果通知多个观察者,则只调用一个,ios,nsnotificationcenter,nsnotification,Ios,Nsnotificationcenter,Nsnotification,我有两名观察员注册。其中一个在appDelegate中,另一个在myViewController中。当我在myViewController中时,我只希望得到两个通知,一个来自全局执行某个方法的appDelegate,另一个来自执行其他方法的myViewController。但是,只调用appDelegate中的一个。如果删除appDelegate中的观察者,将调用myViewController中的观察者。实际上,我可以在appDelegate中使用observer方法,找到当前的视图控制器,并

我有两名观察员注册。其中一个在appDelegate中,另一个在myViewController中。当我在myViewController中时,我只希望得到两个通知,一个来自全局执行某个方法的appDelegate,另一个来自执行其他方法的myViewController。但是,只调用appDelegate中的一个。如果删除appDelegate中的观察者,将调用myViewController中的观察者。实际上,我可以在appDelegate中使用observer方法,找到当前的视图控制器,并在myViewController中执行该方法的代码。但是,我只是不想搞砸你。这两种方法的代码相同,但调用viewWillEnglishe()方法时,我删除了myViewController中的观察者。有什么想法吗?谢谢

appDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] addObserver:self   
                                             selector:@selector(someMethod:)
                                                 name:@"someName"
                                               object:nil];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                        object:nil
                                                      userInfo:someUserInfo];
}

- (void)someMethod:(NSNotification *)notification
{
    // gets called
}
myViewController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(someMethod:)
                                                 name:@"someName"
                                               object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:@"someName"
                                                  object:nil];

    [super viewWillDisappear:animated];
}

- (void)someMethod:(NSNotification *)notification
{
    // not called
}

在下面的代码中,您在观察之前发布

 (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                        object:nil
                                                      userInfo:someUserInfo];

    [[NSNotificationCenter defaultCenter] addObserver:self   
                                             selector:@selector(someMethod:)
                                                 name:@"someName"
                                               object:nil];
}
*原创* 这里有很多可能的问题:

其中一个通知名可能拼写错误=@“someName”-如果这是其他类的红色,请考虑创建一个

在a.h中(两个类都导入) 包括

在相应的.m中

NSString * const XXXSomeNameForSomeNotification = @"someName";
这是确保他们都遵守/发布正确通知的一种方法


如果这不是您的问题,那么尝试添加观察来自ViewDiLoad的通知或在ViewDid之前调用的另一个方法,因为它可能在通知实际发布时未观察到您的通知。添加断点以观察此情况。

我认为根据您发布的代码,原因是

- (void)viewWillDisappear:(BOOL)animated
{

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

[super viewWillDisappear:animated];

}
如果当前视图不在屏幕上,上述方法将删除通知

此外,您可能还需要移动

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


这样,只有在删除视图控制器窗体内存时,才能停止观察通知。如果您在屏幕上,您可能希望签入调用的方法。

看起来,您的通知是在加载视图之前发布的。请参阅添加一些日志

或者试试这个-

    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                            object:nil
                                                          userInfo:someUserInfo];
    });

发布用于发布通知的代码。此外,您在哪里注册/删除您的观察员?谢谢您的评论。我已经编辑了这篇文章。看一看。不要在你的应用程序代理中添加额外的代码。这不是它的目的!!!实际上,发布是从推送通知开始的,这意味着两个观察者都已注册。因为我运行应用程序,appDelegate中的观察者得到注册,然后转到myViewController,调用ViewWillAspect()方法并注册其中的观察者。然后,推送通知来了,我发布了只在appDelegate中触发该方法的通知。如果我删除appDelegate中的观察者并重新运行应用程序并转到myViewController,则会调用其中的观察者。感谢您的回复。事实上,我就是这样做的。我只是提供了一个完全相同的伪代码。我只是不想太啰嗦:),你说得对。但是,实际上我在发布之前添加了一个观察者。代码是错误的。对不起,我弄错了。我已更新。请尝试更改通知的名称。您是否设置了断点,以查看运行应用程序时触发的顺序,以及100%不工作的情况,即指示器是什么。您是对的。我在发布之前删除了观察家。因为当我收到推送通知时,应用程序会显示另一个视图控制器,myViewController的viewWillEnglishe()会被调用并删除观察者。谢谢。谢谢你的回复。为什么?我只是删除myViewController中的观察者,而不是从appDelegate中删除。在修改之前,您在添加之前发布了通知,以确保它不会调用appDelegate。appdelegate肯定会发出一个征求您意见的通知。但是,无论是哪一类,它都不是为了那些人而被删除的。因为每当你们的viewcontroller从屏幕上消失时,它就会调用那个消失方法。请看一下我最后的评论。感谢您的viewcontroller您在哪里调用通知?对于appdelegate,您正在这样做,但对于viewcontroller,您没有这样做。@Sukhrob您可以按照iosDevSi所建议的方法进行操作。这将是一个更好的。谢谢你的答复。是的,你说得对。请看一下我最后添加的评论。
- (void) dealloc
{
       [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:@"someName"
                                                  object:nil];
}
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

        [[NSNotificationCenter defaultCenter] postNotificationName:@"someName"
                                                            object:nil
                                                          userInfo:someUserInfo];
    });