1

I am interesting if it possible to substitute the method body of UIWebView in a runtime? I can't subclass UIWebView

For instance, I need to implement:

- (void) paste:(id)sender;
or
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender;
velkopopovizky
  • 148
  • 2
  • 7

2 Answers2

4

Have you tried out the runtime method method_setImplementation?

Like so:

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);
    …
}

Using the originalPaste you can perform a super call within your implementation.

Tilo Prütz
  • 1,766
  • 3
  • 16
  • 27
  • Cool, exactly I was looking for such decision. I've tried it, but it seems not working, don't know why. Maybe it's because, UIResponderStandardEditActions is category ( – velkopopovizky Jul 06 '12 at 09:48
  • Okay, forget my first (deleted) comment. I think the class_getInstanceMethod() should give the currently used method (maybe from category) but I have not tested it. If so, the method_setImplementation() should replace the currently used method. Then the reason why it is not working would have nothing to do with categories. – Tilo Prütz Jul 09 '12 at 08:31
  • I've already tried both class_replaceMethod(...) and method_setImplementation(...) – velkopopovizky Jul 09 '12 at 11:29
  • Maybe your implementation replacement is replaced later on due to lazy loading of categories or dynamic loading of libraries. – Tilo Prütz Jul 12 '12 at 11:05
  • It think it's correct answer to my question. I can replace those methods, but it doesn't solve UIMenuController issue. – velkopopovizky Jul 13 '12 at 10:10
  • I just want to add single line in original implementation, now i can perform code of my new method, but what to do if i want to call original implementation from my newPaste or method – Mehul Thakkar May 02 '14 at 06:15
  • Is it possible to get only arguments values(not type) at runtime in my method, without modifying original methods. – Mehul Thakkar May 02 '14 at 07:34
2

Yes, but don't do it often, says Apple:

Although the Objective-C language currently allows you to use a category to override methods the class inherits, or even methods declared in the class interface, you are strongly discouraged from doing so. A category is not a substitute for a subclass. There are several significant shortcomings to using a category to override methods:

When a category overrides an inherited method, the method in the category can, as usual, invoke the inherited implementation via a message to super. However, if a category overrides a method that exists in the category's class, there is no way to invoke the original implementation.

A category cannot reliably override methods declared in another category of the same class.

This issue is of particular significance because many of the Cocoa classes are implemented using categories. A framework-defined method you try to override may itself have been implemented in a category, and so which implementation takes precedence is not defined.

The very presence of some category methods may cause behavior changes across all frameworks. For example, if you override the windowWillClose: delegate method in a category on NSObject, all window delegates in your program then respond using the category method; the behavior of all your instances of NSWindow may change. Categories you add on a framework class may cause mysterious changes in behavior and lead to crashes.

Other than that, your life is gonna get pretty hard without subclassing. Even the runtime way of doing this (overriding the IMP's) would involve "subclassing" (allocating a class pair).

Community
  • 1
  • 1
CodaFi
  • 43,043
  • 8
  • 107
  • 153
  • Get thee to [this question](http://stackoverflow.com/questions/11346020/when-are-categories-bad-or-dangerous), that snippet of documentation would be useful there. – jrturton Jul 05 '12 at 14:17
  • Naw, they're apple docs. Feel free to use it in your answer, though! – CodaFi Jul 05 '12 at 14:24
  • Done. That's a tricky bit of copy and paste to do on a phone! – jrturton Jul 05 '12 at 14:29
  • Yeah. I can't wait until they mainstream OS 6. Maybe SO'll finally let us have some semblance of an editing sandbox and image uploads. – CodaFi Jul 05 '12 at 14:31
  • Category won't work in my case with UIWebView. I am asking this question, because it doesn't work in standart way =) – velkopopovizky Jul 05 '12 at 14:48
  • Like I said, your hands are tied, it's either subclass, runtime subclass, or category. – CodaFi Jul 05 '12 at 14:49