Intercept method call in Objective-C

后端 未结 10 1398
被撕碎了的回忆
被撕碎了的回忆 2020-12-02 13:34

Can I intercept a method call in Objective-C? How?

Edit: Mark Powell\'s answer gave me a partial solution, the -forwardInvocation

相关标签:
10条回答
  • 2020-12-02 14:27

    Perhaps you want NSObject's -forwardInvocation method. This allows you to capture a message, retarget it and then resend it.

    0 讨论(0)
  • 2020-12-02 14:28

    To do something when a method is called, you could try an events based approach. So when the method is called, it broadcasts an event, which is picked up by any listeners. I'm not great with objective C, but I just figured out something similar using NSNotificationCenter in Cocoa.

    But if by "intercept" you mean "stop", then maybe you need more logic to decide wether the method should be called at all.

    0 讨论(0)
  • 2020-12-02 14:29

    You do it by swizzling the method call. Assuming you want to grab all releases to NSTableView:

    static IMP gOriginalRelease = nil;
    static void newNSTableViewRelease(id self, SEL releaseSelector, ...) {
       NSLog(@"Release called on an NSTableView");
       gOriginalRelease(self, releaseSelector);
    }
    
    
      //Then somewhere do this:
      gOriginalRelease = class_replaceMethod([NSTableView class], @selector(release), newNSTableViewRelease, "v@:");
    

    You can get more details in the Objective C runtime documentation.

    0 讨论(0)
  • 2020-12-02 14:37

    If you only want to log messages called from the outside (usually called from delegates; to see which kind of messages, when, etc.), you can override respondsToSelector like this:

    - (BOOL)respondsToSelector:(SEL)aSelector {
    NSLog(@"respondsToSelector called for '%@'", NSStringFromSelector(aSelector));
    
    // look up, if a method is implemented
    if([[self class] instancesRespondToSelector:aSelector]) return YES;
    
    return NO;
    

    }

    0 讨论(0)
提交回复
热议问题