1

如果可以在运行时替换 UIWebView 的方法体,我会很有趣吗?我不能继承 UIWebView

例如,我需要实现:

- (void) paste:(id)sender;
or
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender;
4

2 回答 2

4

您是否尝试过运行时方法method_setImplementation

像这样:

static IMP originalPaste = NULL;

void myPaste(id rcv, SEL cmd, id sender)
{
    // Your implementation here
}

…
{
    …
    Method m = class_getInstanceMethod([UIWebView class], @selector(paste:));
    originalPaste = method_setImplementation(m, myPaste);
    …
}

使用originalPaste您可以在您的实现中执行超级调用。

于 2012-07-06T07:14:38.053 回答
2

是的,但不要经常这样做,Apple 说:

尽管 Objective-C 语言目前允许您使用类别来覆盖类继承的方法,甚至是类接口中声明的方法,但强烈建议您不要这样做。类别不能替代子类。使用类别来覆盖方法有几个明显的缺点:

当一个类别覆盖一个继承的方法时,该类别中的方法可以像往常一样通过消息调用继承的实现给super。但是,如果一个类别覆盖了该类别的类中存在的方法,则无法调用原始实现。

一个类别不能可靠地覆盖在同一类的另一个类别中声明的方法。

这个问题特别重要,因为许多 Cocoa 类是使用类别实现的。您尝试覆盖的框架定义的方法本身可能已经在一个类别中实现,因此没有定义哪个实现优先。

某些类别方法的存在可能会导致所有框架的行为发生变化。例如,如果您在 NSObject 的一个类别中覆盖 windowWillClose: 委托方法,那么您程序中的所有窗口委托都会使用该类别方法进行响应;您的所有 NSWindow 实例的行为可能会改变。您在框架类上添加的类别可能会导致行为的神秘变化并导致崩溃。

除此之外,如果没有子类化,你的生活会变得非常艰难。甚至执行此操作的运行时方式(覆盖 IMP)也会涉及“子类化”(分配类对)。

于 2012-07-05T14:00:44.677 回答