2011-09-12 18 views
2

我正在使用PyObjC。 PyObjC不提供到method_exchangeImplementations的接口,所以我試圖通過ctypes使用該函數。我試圖從某些窗口控制器類中覆蓋windowShouldClose:PyObjC和method_exchangeImplementations:崩潰。正確的用法?

我的代碼:

import objc 
BrowserWindowController = objc.lookUpClass("BrowserWindowController") 

class BrowserWindowController(objc.Category(BrowserWindowController)): 
    def myWindowShouldClose_(self, sender): 
     print "myWindowShouldClose", self, sender 
     return self.myWindowShouldClose_(sender) 

from ctypes import * 
capi = pythonapi 

# id objc_getClass(const char *name) 
capi.objc_getClass.restype = c_void_p 
capi.objc_getClass.argtypes = [c_char_p] 

# SEL sel_registerName(const char *str) 
capi.sel_registerName.restype = c_void_p 
capi.sel_registerName.argtypes = [c_char_p] 

def capi_get_selector(name): 
    return c_void_p(capi.sel_registerName(name)) 

# Method class_getInstanceMethod(Class aClass, SEL aSelector) 
# Will also search superclass for implementations. 
capi.class_getInstanceMethod.restype = c_void_p 
capi.class_getInstanceMethod.argtypes = [c_void_p, c_void_p] 

# void method_exchangeImplementations(Method m1, Method m2) 
capi.method_exchangeImplementations.restype = None 
capi.method_exchangeImplementations.argtypes = [c_void_p, c_void_p] 

def hook_into_close(): 
    clazz = capi.objc_getClass("BrowserWindowController") 
    origClose = capi.class_getInstanceMethod(clazz, capi_get_selector("windowShouldClose:")) 
    newClose = capi.class_getInstanceMethod(clazz, capi_get_selector("myWindowShouldClose:")) 
    capi.method_exchangeImplementations(origClose, newClose) 

此崩潰。在[NSWindow _close]有一些奇怪的回溯。

代碼基本正確嗎?

什麼問題?

+0

BrowserWindowController是你的類嗎?如果是這樣,你爲什麼要爲不同的實現交換實現,而不僅僅是在自己的實現中做你需要做的事情? –

+0

@彼得:不,它來自另一個我無法改變實現的框架。 – Albert

回答

1

啊,當我在def myWindowShouldClose_之前加@objc.signature(BrowserWindowController.windowWillClose_.signature)時,它不會再崩潰了。

所以它只是錯誤的/不匹配的簽名。