简体   繁体   中英

Race condition removing local event monitor in event handler in Objective-C using Cocoa

I am creating a local event monitor in Objective-C using the Cocoa framework and wondered if this would introduce a race condition or not:

id monitor = [NSEvent addLocalMonitorForEventsMatchingMask:
    (NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown | NSEventMaskOtherMouseDown)
    handler:^(NSEvent* event)
    {
        [NSEvent removeMonitor:monitor];
    }];

Your code does not compile as the block does not return a value, so maybe you've simplified this too much for posting.

Next the value of monitor within the block will always be nil as its value is copied as part of block construction before addLocalMonitorForEventsMatchingMask returns and a value is assigned to monitor .

You could address this last issue by declaring monitor to be __block , thus capturing the variable rather than its value, however that gets you to:

You've got a reference cycle. The opaque monitor object returned by addLocalMonitorForEventsMatchingMask contains within it a reference to your block, and your block contains a reference to the monitor object. This won't effect the operation of the monitoring or its removal, it will just mean the monitor object & block objects will never get collected. You could address this by nil ing monitor in the block when you do removeMonitor .

Which gets us to your final question, is there a race condition? Presumably you mean between the event system calling your monitor for one event and trying to call it on a following event. I don't know if we can say for sure, however the documentation for removeMonitor does not mention any precautions to take, and initial event processing is done through a "queue" suggesting the system will not start processing a following event until it has at least dispatched the current one to your app. This does strongly suggest that race conditions are not an issue here.

Note however that the documentation, even the Swift version, uses the term "garbage collection" and though ARC is a type of GC Apple tends to reserve the term for the long deprecated pre-ARC (and pre-Swift) garbage collector - suggesting the documentation has not been revised for eons (in computer terms). Maybe someone else will offer a definitive answer on this.

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM