Reputation: 1252
I am trying to perform a selector when certain events occur such as:
I am posting a notification when these events occur with the following code
[[NSNotificationCenter defaultCenter] postNotificationName:Notif_Name object:nil];
and I want to perform a selector when the notification is received in the same UIViewController
instance, so I'm registering it as an observer in viewDidLoad
[[NSNotificationCenter defaultCenter] addObserverForName:Notif_Name object:nil queue:nil usingBlock:^(NSNotification *note) {
[self performSelectorOnMainThread:@selector(selectorName) withObject:nil waitUntilDone:NO];
}];
Now, these events I'm observing may happen simultaneously. How do I make sure that my selector is performed only once?
Upvotes: 1
Views: 419
Reputation: 64002
Coalescing of notifications is supported by NSNotificationQueue
in Cocoa Touch.
Instead of using the notification center to post the notification directly, enqueue the notification and tell the queue to combine similar or identical notifications. You can have it match based on either or both of the notification name and sender. You're not providing an object for the notification, so you can only coalesce using the name.
NSNotification * note = [NSNotification notificationWithName:Notif_Name object:nil]
[[NSNotificationQueue defaultQueue] enqueueNotification:note
postingStyle:NSPostASAP
coalesceMask:NSNotificationCoalescingOnName
forModes:nil];
Upvotes: 2
Reputation: 14030
you could also try the following:
[[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];
}];
you wait a second until you perform the action and cancel all pending requests...
Upvotes: 0
Reputation: 41
You can keep a flag telling you whether selectorName has been executed and protect it against multithreaded access.
@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
Upvotes: 0