Utility methods for threading¶
NSObject
has a number of methods for calling selectors in different
contexts, such as after a delay or on another thread.
These methods can be called from Python (of course), but you need to be a bit careful because the implementation of these methods won’t catch exceptions for you and therefore an uncaught exception in your python code can cause the runloop to stop due to an exception, which might terminate your program.
To make matters worse, due to a bug in Python 2.5 this will cause a hard
crash (segmentation fault) when this happens with
performSelectorOnMainThread:withObject:waitUntilDone:
.
Because of this PyObjC 2.1 provides a category on NSObject
that implements
safe alternatives to the stock NSObject
methods.
Safe replacements for stock NSObject
methods¶
These safe replacements have the same signature as the stock NSObject
methods, but will log exceptions instead of letting them escape into the rest
of your program.
pyobjc_performSelector_onThread_withObject_waitUntilDone_
This is the safe alternative for
performSelector_onThread_withObject_waitUntilDone_
.(Introduced in macOS 10.5)
pyobjc_performSelector_onThread_withObject_waitUntilDone_modes_
This is the safe alternative for
performSelector_onThread_withObject_waitUntilDone_modes_
.(Introduced in macOS 10.5)
pyobjc_performSelector_withObject_afterDelay_
This is the safe alternative for
performSelector_withObject_afterDelay_
.pyobjc_performSelector_withObject_afterDelay_inModes_
This is the safe alternative for
performSelector_withObject_afterDelay_inModes_
.pyobjc_performSelectorInBackground_withObject_
This is the safe alternative for
performSelectorInBackground_withObject_
.(Introduced in macOS 10.5)
pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_
This is the safe alternative for
performSelectorOnMainThread_withObject_waitUntilDone_
.pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_modes_
This is the safe alternative for
performSelectorOnMainThread_withObject_waitUntilDone_modes_
.
Enhanced methods¶
The stock methods are quite useful, but at times it is useful to get the result back from the other thread. The methods below will call the selector on another thread and will return the result from that call in the current thread. If the call on the “other” thread raises an exception this exception will be reraised in the current thread.
Note: these methods are synchronous, that is, they block the current thread until the call on the “other” thread is done.
As an example:
1 class MyClass (NSObject): 2 3 def divideByZero_(self, arg): 4 return arg/0 5 6 def doit(self): 7 try: 8 result = self.performSelectorOnMainThread_withObject_( 9 'divideByZero:', 55) 10 print result 11 12 except: 13 print "Division failed"
The available methods are:
pyobjc_performSelector_onThread_withObject_(selector, thread, arg)
(Introduced in macOS 10.5)
pyobjc_performSelector_onThread_withObject_modes_(selector, thread, arg, modes)
(Introduced in macOS 10.5)
pyobjc_performSelectorOnMainThread_withObject_(selector, arg)
pyobjc_performSelectorOnMainThread_withObject_modes_(selector, arg, modes)