我正在寻找一种方法来记录对给定UIView的每个方法的每次调用以进行调试。
答案 0 :(得分:3)
This is the code I wrote to do it
使用以下步骤:
NSProxy
allocWithZone:
并使用代理类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>