PyObjC и method_exchangeImplementations: сбой. правильное использование?

Я использую PyObjC. PyObjC не предоставляет интерфейс для method_exchangeImplementations, поэтому я пытался использовать эту функцию через ctypes. Я пытался перезаписать windowShouldClose: из какого-то класса оконного контроллера.

Мой код:

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].

Код в принципе правильный?

В чем проблема?


person Albert    schedule 12.09.2011    source источник
comment
Является ли BrowserWindowController вашим классом? Если да, то почему вы меняете его реализацию на другую, а не просто делаете то, что вам нужно делать в своей собственной реализации?   -  person Peter Hosey    schedule 12.09.2011
comment
@Peter: Нет, это исходит из другого фреймворка, где я не могу изменить реализацию.   -  person Albert    schedule 13.09.2011


Ответы (1)


Ах, когда я добавляю @objc.signature(BrowserWindowController.windowWillClose_.signature) перед def myWindowShouldClose_, он больше не вылетает.

Так что это просто была неправильная/несоответствующая подпись.

person Albert    schedule 12.09.2011