"""
Define a category on NSObject with some useful methods.
FIXME:
- add signature information (namedSelector) to all methods
(not strictly needed)
- add docstrings everywhere
- create unittests
"""
import objc
import sys
NSObject = objc.lookUpClass('NSObject')
class NSObject (objc.Category(NSObject)):
@objc.namedSelector(b"_pyobjc_performOnThread:")
def _pyobjc_performOnThread_(self, callinfo):
try:
sel, arg = callinfo
m = self.methodForSelector_(sel)
m(arg)
except:
import traceback
traceback.print_exc(fp=sys.stderr)
@objc.namedSelector(b"_pyobjc_performOnThreadWithResult:")
def _pyobjc_performOnThreadWithResult_(self, callinfo):
try:
sel, arg, result = callinfo
m = self.methodForSelector_(sel)
r = m(arg)
result.append((True, r))
except:
result.append((False, sys.exc_info()))
if hasattr(NSObject, "performSelector_onThread_withObject_waitUntilDone_"):
@objc.namedSelector(b"pyobjc_performSelector:onThread:withObject:waitUntilDone:")
def pyobjc_performSelector_onThread_withObject_waitUntilDone_(
self, aSelector, thread, arg, wait):
"""
A version of performSelector:onThread:withObject:waitUntilDone: that
will log exceptions in the called method (instead of aborting the
NSRunLoop on the other thread).
"""
self.performSelector_onThread_withObject_waitUntilDone_(
'pyobjc_performOnThread:', thread, (aSelector, arg), wait)
@objc.namedSelector(b"pyobjc_performSelector:onThread:withObject:waitUntilDone:modes:")
def pyobjc_performSelector_onThread_withObject_waitUntilDone_modes_(
self, aSelector, thread, arg, wait, modes):
"""
A version of performSelector:onThread:withObject:waitUntilDone:modes:
that will log exceptions in the called method (instead of aborting the
NSRunLoop on the other thread).
"""
self.performSelector_onThread_withObject_waitUntilDone_modes_(
'pyobjc_performOnThread:', thread, (aSelector, arg), wait, modes)
@objc.namedSelector(b"pyobjc_performSelector:withObject:afterDelay:")
def pyobjc_performSelector_withObject_afterDelay_(
self, aSelector, arg, delay):
"""
A version of performSelector:withObject:afterDelay:
that will log exceptions in the called method (instead of aborting the
NSRunLoop).
"""
self.performSelector_withObject_afterDelay_(
'pyobjc_performOnThread:', (aSelector, arg), delay)
@objc.namedSelector(b"pyobjc_performSelector:withObject:afterDelay:inModes:")
def pyobjc_performSelector_withObject_afterDelay_inModes_(
self, aSelector, arg, delay, modes):
"""
A version of performSelector:withObject:afterDelay:inModes:
that will log exceptions in the called method (instead of aborting the
NSRunLoop).
"""
self.performSelector_withObject_afterDelay_inModes_(
'pyobjc_performOnThread:', (aSelector, arg), delay, modes)
if hasattr(NSObject, "performSelectorInBackground_withObject_waitUntilDone_"):
@objc.namedSelector(b"pyobjc_performSelectorInBackground:withObject:")
def pyobjc_performSelectorInBackground_withObject_(
self, aSelector, arg):
"""
A version of performSelectorInBackground:withObject:
that will log exceptions in the called method (instead of aborting the
NSRunLoop).
"""
self.performSelectorInBackground_withObject_(
'pyobjc_performOnThread:', (aSelector, arg))
@objc.namedSelector(b"pyobjc_performSelectorInBackground:withObject:waitUntilDone:")
def pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_(
self, aSelector, arg, wait):
"""
A version of performSelectorOnMainThread:withObject:waitUntilDone:
that will log exceptions in the called method (instead of aborting the
NSRunLoop in the main thread).
"""
self.performSelectorOnMainThread_withObject_waitUntilDone_(
'pyobjc_performOnThread:', (aSelector, arg), wait)
@objc.namedSelector(b"pyobjc_performSelectorOnMainThread:withObject:waitUntilDone:modes:")
def pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_modes_(
self, aSelector, arg, wait, modes):
"""
A version of performSelectorOnMainThread:withObject:waitUntilDone:modes:
that will log exceptions in the called method (instead of aborting the
NSRunLoop in the main thread).
"""
self.performSelectorOnMainThread_withObject_waitUntilDone_modes_(
'pyobjc_performOnThread:', (aSelector, arg), wait, modes)
# And some a some versions that return results
@objc.namedSelector(b"pyobjc_performSelectorOnMainThread:withObject:modes:")
def pyobjc_performSelectorOnMainThread_withObject_modes_(
self, aSelector, arg, modes):
"""
Simular to performSelectorOnMainThread:withObject:waitUntilDone:modes:,
but:
- always waits until done
- returns the return value of the called method
- if the called method raises an exception, this will raise the same
exception
"""
result = []
self.performSelectorOnMainThread_withObject_waitUntilDone_modes_(
'pyobjc_performOnThreadWithResult:',
(aSelector, arg, result), True, modes)
isOK, result = result[0]
if isOK:
return result
else:
exc_type, exc_value, exc_trace = result
raise exc_type, exc_value, exc_trace
@objc.namedSelector(b"pyobjc_performSelectorOnMainThread:withObject:")
def pyobjc_performSelectorOnMainThread_withObject_(
self, aSelector, arg):
result = []
self.performSelectorOnMainThread_withObject_waitUntilDone_(
'pyobjc_performOnThreadWithResult:',
(aSelector, arg, result), True)
isOK, result = result[0]
if isOK:
return result
else:
exc_type, exc_value, exc_trace = result
raise exc_type, exc_value, exc_trace
if hasattr(NSObject, "performSelector_onThread_withObject_waitUntilDone_"):
# These methods require Leopard, don't define them if the
# platform functionality isn't present.
@objc.namedSelector(b"pyobjc_performSelector:onThread:withObject:modes:")
def pyobjc_performSelector_onThread_withObject_modes_(
self, aSelector, thread, arg, modes):
result = []
self.performSelector_onThread_withObject_waitUntilDone_modes_(
'pyobjc_performOnThreadWithResult:', thread,
(aSelector, arg, result), True, modes)
isOK, result = result[0]
if isOK:
return result
else:
exc_type, exc_value, exc_trace = result
raise exc_type, exc_value, exc_trace
@objc.namedSelector(b"pyobjc_performSelector:onThread:withObject:")
def pyobjc_performSelector_onThread_withObject_(
self, aSelector, thread, arg):
result = []
self.performSelector_onThread_withObject_waitUntilDone_(
'pyobjc_performOnThreadWithResult:', thread,
(aSelector, arg, result), True)
isOK, result = result[0]
if isOK:
return result
else:
exc_type, exc_value, exc_trace = result
raise exc_type, exc_value, exc_trace
del NSObject
|