1""" 2Define a category on NSObject with some useful methods. 3 4FIXME: 5- add signature information (namedselector) to all methods 6 (not strictly needed) 7- add docstrings everywhere 8- create unittests 9""" 10import objc 11import sys 12 13NSObject = objc.lookUpClass('NSObject') 14 15class NSObject (objc.Category(NSObject)): 16 17 @objc.namedselector("_pyobjc_performOnThread:") 18 def _pyobjc_performOnThread_(self, callinfo): 19 try: 20 sel, arg = callinfo 21 m = self.methodForSelector_(sel) 22 m(arg) 23 except: 24 import traceback 25 traceback.print_exc(fp=sys.stderr) 26 27 @objc.namedselector("_pyobjc_performOnThreadWithResult:") 28 def _pyobjc_performOnThreadWithResult_(self, callinfo): 29 try: 30 sel, arg, result = callinfo 31 m = self.methodForSelector_(sel) 32 r = m(arg) 33 result.append((True, r)) 34 except: 35 result.append((False, sys.exc_info())) 36 37 38 if hasattr(NSObject, "performSelector_onThread_withObject_waitUntilDone_"): 39 @objc.namedselector("pyobjc_performSelector:onThread:withObject:waitUntilDone:") 40 def pyobjc_performSelector_onThread_withObject_waitUntilDone_( 41 self, aSelector, thread, arg, wait): 42 """ 43 A version of performSelector:onThread:withObject:waitUntilDone: that 44 will log exceptions in the called method (instead of aborting the 45 NSRunLoop on the other thread). 46 """ 47 self.performSelector_onThread_withObject_waitUntilDone_( 48 'pyobjc_performOnThread:', thread, (aSelector, arg), wait) 49 50 @objc.namedselector("pyobjc_performSelector:onThread:withObject:waitUntilDone:modes:") 51 def pyobjc_performSelector_onThread_withObject_waitUntilDone_modes_( 52 self, aSelector, thread, arg, wait, modes): 53 """ 54 A version of performSelector:onThread:withObject:waitUntilDone:modes: 55 that will log exceptions in the called method (instead of aborting the 56 NSRunLoop on the other thread). 57 """ 58 self.performSelector_onThread_withObject_waitUntilDone_modes_( 59 'pyobjc_performOnThread:', thread, (aSelector, arg), wait, modes) 60 61 @objc.namedselector("pyobjc_performSelector:withObject:afterDelay:") 62 def pyobjc_performSelector_withObject_afterDelay_( 63 self, aSelector, arg, delay): 64 """ 65 A version of performSelector:withObject:afterDelay: 66 that will log exceptions in the called method (instead of aborting the 67 NSRunLoop). 68 """ 69 self.performSelector_withObject_afterDelay_( 70 'pyobjc_performOnThread:', (aSelector, arg), delay) 71 72 @objc.namedselector("pyobjc_performSelector:withObject:afterDelay:inModes:") 73 def pyobjc_performSelector_withObject_afterDelay_inModes_( 74 self, aSelector, arg, delay, modes): 75 """ 76 A version of performSelector:withObject:afterDelay:inModes: 77 that will log exceptions in the called method (instead of aborting the 78 NSRunLoop). 79 """ 80 self.performSelector_withObject_afterDelay_inModes_( 81 'pyobjc_performOnThread:', (aSelector, arg), delay, modes) 82 83 if hasattr(NSObject, "performSelectorInBackground_withObject_waitUntilDone_"): 84 @objc.namedselector("pyobjc_performSelectorInBackground:withObject:") 85 def pyobjc_performSelectorInBackground_withObject_( 86 self, aSelector, arg): 87 """ 88 A version of performSelectorInBackground:withObject: 89 that will log exceptions in the called method (instead of aborting the 90 NSRunLoop). 91 """ 92 self.performSelectorInBackground_withObject_( 93 'pyobjc_performOnThread:', (aSelector, arg)) 94 95 96 @objc.namedselector("pyobjc_performSelectorInBackground:withObject:waitUntilDone:") 97 def pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_( 98 self, aSelector, arg, wait): 99 """ 100 A version of performSelectorOnMainThread:withObject:waitUntilDone: 101 that will log exceptions in the called method (instead of aborting the 102 NSRunLoop in the main thread). 103 """ 104 self.performSelectorOnMainThread_withObject_waitUntilDone_( 105 'pyobjc_performOnThread:', (aSelector, arg), wait) 106 107 @objc.namedselector("pyobjc_performSelectorOnMainThread:withObject:waitUntilDone:modes:") 108 def pyobjc_performSelectorOnMainThread_withObject_waitUntilDone_modes_( 109 self, aSelector, arg, wait, modes): 110 """ 111 A version of performSelectorOnMainThread:withObject:waitUntilDone:modes: 112 that will log exceptions in the called method (instead of aborting the 113 NSRunLoop in the main thread). 114 """ 115 self.performSelectorOnMainThread_withObject_waitUntilDone_modes_( 116 'pyobjc_performOnThread:', (aSelector, arg), wait, modes) 117 118 119 # And some a some versions that return results 120 121 @objc.namedselector("pyobjc_performSelectorOnMainThread:withObject:modes:") 122 def pyobjc_performSelectorOnMainThread_withObject_modes_( 123 self, aSelector, arg, modes): 124 """ 125 Simular to performSelectorOnMainThread:withObject:waitUntilDone:modes:, 126 but: 127 128 - always waits until done 129 - returns the return value of the called method 130 - if the called method raises an exception, this will raise the same 131 exception 132 """ 133 result = [] 134 self.performSelectorOnMainThread_withObject_waitUntilDone_modes_( 135 'pyobjc_performOnThreadWithResult:', 136 (aSelector, arg, result), True, modes) 137 isOK, result = result[0] 138 139 if isOK: 140 return result 141 else: 142 exc_type, exc_value, exc_trace = result 143 raise exc_type, exc_value, exc_trace 144 145 @objc.namedselector("pyobjc_performSelectorOnMainThread:withObject:") 146 def pyobjc_performSelectorOnMainThread_withObject_( 147 self, aSelector, arg): 148 result = [] 149 self.performSelectorOnMainThread_withObject_waitUntilDone_( 150 'pyobjc_performOnThreadWithResult:', 151 (aSelector, arg, result), True) 152 isOK, result = result[0] 153 154 if isOK: 155 return result 156 else: 157 exc_type, exc_value, exc_trace = result 158 raise exc_type, exc_value, exc_trace 159 160 if hasattr(NSObject, "performSelector_onThread_withObject_waitUntilDone_"): 161 # These methods require Leopard, don't define them if the 162 # platform functionality isn't present. 163 164 @objc.namedselector("pyobjc_performSelector:onThread:withObject:modes:") 165 def pyobjc_performSelector_onThread_withObject_modes_( 166 self, aSelector, thread, arg, modes): 167 result = [] 168 self.performSelector_onThread_withObject_waitUntilDone_modes_( 169 'pyobjc_performOnThreadWithResult:', thread, 170 (aSelector, arg, result), True, modes) 171 isOK, result = result[0] 172 173 if isOK: 174 return result 175 else: 176 exc_type, exc_value, exc_trace = result 177 raise exc_type, exc_value, exc_trace 178 179 @objc.namedselector("pyobjc_performSelector:onThread:withObject:") 180 def pyobjc_performSelector_onThread_withObject_( 181 self, aSelector, thread, arg): 182 result = [] 183 self.performSelector_onThread_withObject_waitUntilDone_( 184 'pyobjc_performOnThreadWithResult:', thread, 185 (aSelector, arg, result), True) 186 isOK, result = result[0] 187 188 if isOK: 189 return result 190 else: 191 exc_type, exc_value, exc_trace = result 192 raise exc_type, exc_value, exc_trace 193 194 195del NSObject 196