有没有办法记录给定类的每个方法的每个调用?

时间:2014-10-22 00:21:17

标签: ios objective-c debugging uiview

我正在寻找一种方法来记录对给定UIView的每个方法的每次调用以进行调试。

2 个答案:

答案 0 :(得分:3)

This is the code I wrote to do it

使用以下步骤:

  1. 通过NSProxy
  2. 的子类创建代理类
  3. 目标类上的Swizzle allocWithZone:并使用代理类
  4. 包装返回的对象
  5. 在代理类
  6. forwardInvocation:中记录消息
    #import <objc/runtime.h>
    
    @interface XLCProxy : NSProxy
    
    + (id)proxyWithObject:(id)obj;
    
    @end
    
    @implementation XLCProxy
    {
        id _obj;
    }
    
    + (void)load
    {
        {
            Class cls = NSClassFromString(@"IDESourceCodeDocument");
            id metacls = object_getClass(cls);
            IMP imp = class_getMethodImplementation(metacls, @selector(allocWithZone:));
            IMP newimp = imp_implementationWithBlock(^id(id me, SEL cmd, NSZone *zone) {
                id obj = ((id (*)(id,SEL,NSZone*))(imp))(me, cmd, zone);
                return [XLCProxy proxyWithObject:obj];
            });
            BOOL success = class_addMethod(metacls, @selector(allocWithZone:), newimp, [[NSString stringWithFormat:@"@@:%s", @encode(NSZone*)] UTF8String]);
            if (!success) {
                NSLog(@"Add method failed");
            }
        }
    }
    
    + (id)proxyWithObject:(id)obj
    {
        XLCProxy *proxy = [self alloc];
        proxy->_obj = obj;
        return proxy;
    }
    
    - (void)forwardInvocation:(NSInvocation *)invocation
    {
        const char *selname = sel_getName([invocation selector]);
    
        [invocation setTarget:_obj];
        [invocation invoke];
    
        if ([@(selname) hasPrefix:@"init"] && [[invocation methodSignature] methodReturnType][0] == '@') {
            const void * ret;
            [invocation getReturnValue:&ret];
            ret = CFBridgingRetain([XLCProxy proxyWithObject:_obj]);
            [invocation setReturnValue:&ret];
        }
    
    
        NSLog(@"%@ %s", [_obj class], selname);
    //    if ([[invocation methodSignature] methodReturnType][0] == '@') {
    //        NSObject __unsafe_unretained * obj;
    //        [invocation getReturnValue:&obj];
    //        NSLog(@"%@", obj);
    //    }
    }
    
    -(NSMethodSignature *)methodSignatureForSelector:(SEL)sel
    {
        return [_obj methodSignatureForSelector:sel];
    }
    
    - (Class)class
    {
        return [_obj class];
    }
    
    @end
    

答案 1 :(得分:2)

您可以使用DTrace。这是一个单行:

sudo dtrace -q -n 'objc$target:YourClass::entry { printf("%c[%s %s]\n", probefunc[0], probemod, probefunc + 1); }' -p <the PID of the target process>