Notification blocks added via -addNotificationBlock: won't get called when there is an open NSMenu eating events.
Is this normal behavior ? Can we get around this ?
I reproduced the problem in a simple project.
The test class :
@interface TestObject : RLMObject
@property (nonatomic) NSInteger ID;
@property (nonatomic) NSInteger counter;
@end
@implementation TestObject
+(NSString *)primaryKey {
return @"ID";
}
@end
Then, in a view controller :
@interface ViewController ()
@property (strong) RLMNotificationToken *counterToken;
@property (strong) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewWillAppear {
self.counterToken = [[TestObject objectsWhere:@"ID = 3"] addNotificationBlock:^(RLMResults * _Nullable results, NSError * _Nullable error) {
self.textFieldCounter.stringValue = [NSString stringWithFormat:@"%lu", [results.firstObject counter]];
}];
}
- (void)viewWillDisappear {
[self.counterToken stop];
self.counterToken = nil;
}
- (IBAction)startStop:(id)sender {
if (self.timer) {
[self.timer invalidate];
self.timer = nil;
} else {
NSTimer *timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(incrementCounter:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
self.timer = timer;
}
}
- (void)incrementCounter:(NSTimer *)timer {
TestObject *testObjectWithID3 = [TestObject objectsWhere:@"ID = 3"].firstObject;
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
testObjectWithID3.counter++;
[realm addOrUpdateObject:testObjectWithID3];
NSLog(@"%@", testObjectWithID3);
NSLog(@"%@", [TestObject objectsWhere:@"ID = 3"].firstObject);
}];
}
@end
A button fires the timer, and a label displays the counter.
As soon as the main menu is opened, notification blocks aren't called anymore.
I can send the test project if you need it.
@tgoyne Any news about this ?
I wonder if this behavior is expected, or if I do something wrong here ?
This is kinda working as intended. NSMenu switches the run loop into NSEventTrackingRunLoopMode, specifically so that things like our change notifications aren't delivered while the menu is open. I suppose we need to expose the ability to control the runloop mode used for our notifications, but unfortunately it'd need to be a per-Realm thing rather than a per-notification thing.
@tgoyne Thanks for replying.
I suppose we need to expose the ability to control the runloop mode used for our notifications
That would be very helpful indeed. As of now, with this limitation, I subscribe for NSMenuDidEndTrackingNotification notification. But I ultimately would be notified while the menu is open.
@tgoyne: As you proposed that we would need to expose another API here, I promoted this issue to an enhancement. Alternatively we might want to create a new issue instead which goes in place of that and describes what would be needed to do here.
➤ Unito Sync Bot commented:
Transition made by Unito
Most helpful comment
@tgoyne: As you proposed that we would need to expose another API here, I promoted this issue to an enhancement. Alternatively we might want to create a new issue instead which goes in place of that and describes what would be needed to do here.