我正在寻找一种方法来记录对给定 UIView 的每个方法的每次调用,以进行调试。
这是我为此编写的代码 https://github.com/xlc/XLCXcodeAssist/blob/master/XLCXcodeAssist/XLCProxy.m
使用以下步骤:
- 通过子类化创建代理类
NSProxy
- Swizzle
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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)