Objective-C,我如何在另一个类中连接一个方法

Lot*_*har 3 objective-c

Objective-C 将它的所有方法保存在一个巨大的哈希表中 - 所以不应该修补这个表并用我自己的修补方法(然后调用原始方法)替换现有方法吗?

我需要一种方法来连接窗口中的 NSWindow KeyUp 方法,因为它已经创建,我无法子类化它。

我需要一些代码或至少一些可以用于进一步搜索的关键字。

Max*_*ann 5

你不应该为此混淆方法。这是不推荐使用的行为。这将影响您应用程序中的所有窗口,而不仅仅是您想要更改的窗口。但是,您应该做的是已经继承 NSWindow 的子类,然后在运行时更改该窗口的类。这可以使用这个运行时函数来完成:

Class object_setClass(id object, Class cls)
Run Code Online (Sandbox Code Playgroud)

参考在这里:http : //developer.apple.com/mac/library/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/uid/TP40001418-CH1g-SW12

您的代码应如下所示:

object_setClass(theWindow, [MyWindowSubclass class]);
Run Code Online (Sandbox Code Playgroud)

可能遇到的问题是该窗口已经是 NSWindow 的子类。如果是这样的话,有更复杂的方法来实现这一点。您可以在运行时动态构造一个类。这里还有一些代码。鉴于该窗口是目标窗口:

Class newWindowClass = objc_allocateClassPair([window class], "MyHackyWindowSubclass", 0);
Method upMethod = class_getInstanceMethod(newWindowClass, @selector(keyUp:));
method_setImplementation(upMethod, new_NSWindow_keyUp_);
object_setClass(window, newWindowClass);
Run Code Online (Sandbox Code Playgroud)

我不完全确定这不会改变超类的实现。该文档对此有点不具体。但是,您仍然应该尝试一下。如果它不起作用,请用这一行替换第二行和第三行:

class_replaceMethod(newWindowClass, @selector(keyUp:), new_NSWindow_keyUp_, "v@:@");
Run Code Online (Sandbox Code Playgroud)

在任何情况下,您都需要定义新的 Method 实现。它可能看起来像这样(部分来自 KennyTM):

void new_NSWindow_keyUp_(NSWindow* self, SEL _cmd, NSEvent* evt) {
  [super keyUp: evt];
  ... // do your changes
}
Run Code Online (Sandbox Code Playgroud)