我正在尝试在发生某些事件时执行选择器,例如:
我在使用以下代码发生这些事件时发布通知
[[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];
}];
现在,我观察到的这些事件可能同时发生。如何确保我的选择器只执行一次?
答案 0 :(得分:1)
Cocoa Touch中的NSNotificationQueue
支持合并通知。
不使用通知 center 直接发布通知,而是将通知排入队列并告知队列组合相似或相同的通知。您可以根据通知名称和发件人之一或两者匹配它。您没有为通知提供对象,因此您只能使用名称合并。
NSNotification * note = [NSNotification notificationWithName:Notif_Name object:nil]
[[NSNotificationQueue defaultQueue] enqueueNotification:note
postingStyle:NSPostASAP
coalesceMask:NSNotificationCoalescingOnName
forModes:nil];
答案 1 :(得分:0)
您可以保留一个标志,告诉您是否已执行了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
答案 2 :(得分:0)
你也可以尝试以下方法:
[[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];
}];
等待一秒钟,直到您执行操作并取消所有待处理的请求...