Ios 当收到两个或多个通知时,仅执行一次选择器

Ios 当收到两个或多个通知时,仅执行一次选择器,ios,objective-c,cocoa-touch,nsnotificationcenter,nsnotification,Ios,Objective C,Cocoa Touch,Nsnotificationcenter,Nsnotification,我试图在某些事件发生时执行选择器,例如: 应用程序将变为活动状态 internet可访问性状态从“不可访问”更改为“可访问” 当这些事件发生时,我用以下代码发布通知 [[NSNotificationCenter defaultCenter] postNotificationName:Notif_Name object:nil]; 我想在同一个UIViewController实例中收到通知时执行一个选择器,因此我将它注册为viewDidLoad [[NSNotificationCenter de

我试图在某些事件发生时执行选择器,例如:

  • 应用程序将变为活动状态
  • internet可访问性状态从“不可访问”更改为“可访问”
  • 当这些事件发生时,我用以下代码发布通知

    [[NSNotificationCenter defaultCenter] postNotificationName:Notif_Name object:nil];
    
    我想在同一个
    UIViewController
    实例中收到通知时执行一个选择器,因此我将它注册为
    viewDidLoad

    [[NSNotificationCenter defaultCenter] addObserverForName:Notif_Name object:nil queue:nil usingBlock:^(NSNotification *note) {
    
        [self performSelectorOnMainThread:@selector(selectorName) withObject:nil waitUntilDone:NO];
    }];
    

    现在,我观察到的这些事件可能同时发生。如何确保选择器只执行一次?

    您可以保留一个标志,告知是否已执行selectorName,并防止多线程访问

    @interface ViewController ()
    @property (nonatomic) BOOL executed;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(executeSelector) name:Notif_Name object:nil];
    }
    
    - (void)executeSelector {
        @synchronized (self) {
            if (!self.executed) {
                self.executed = YES;
                [[NSNotificationCenter defaultCenter] removeObserver:self];
                [self performSelectorOnMainThread:@selector(selectorName) withObject:nil waitUntilDone:NO];
            }
        }
    }
    
    @end
    

    您也可以尝试以下方法:

    [[NSNotificationCenter defaultCenter] addObserverForName:Notif_Name object:nil queue:nil usingBlock:^(NSNotification *note) {
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(selectorName) object:nil];
      [self performSelector:@selector(selectorName) withObject:nil afterDelay:1.0];
    }];
    

    您等待一秒钟,直到执行该操作并取消所有挂起的请求…

    in-Cocoa Touch支持合并通知

    不要使用通知中心直接发布通知,而是将通知排队,并告诉队列合并类似或相同的通知。您可以根据通知名称和发件人中的一个或两个进行匹配。您没有为通知提供对象,因此只能使用名称合并

    NSNotification * note = [NSNotification notificationWithName:Notif_Name object:nil]
    
    [[NSNotificationQueue defaultQueue] enqueueNotification:note
                                               postingStyle:NSPostASAP
                                               coalesceMask:NSNotificationCoalescingOnName
                                                   forModes:nil];