是否可以在没有子类化的情况下在UIWebView中替换现有方法的主体

时间:2012-07-05 13:56:27

标签: ios uiwebview objective-c-runtime uiresponder

如果可以在运行时替换UIWebView的方法体,我感兴趣吗? 我无法继承UIWebView

例如,我需要实现:

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

2 个答案:

答案 0 :(得分: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,您可以在实施中执行超级电话。

答案 1 :(得分:2)

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

  

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

     

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

     

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

     

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

     

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

除此之外,没有子类化,你的生活将变得非常艰难。即使是这样做的运行时方式(覆盖IMP)也会涉及“子类化”(分配类对)。