iOS|iOS -NSProxy
@interface NSProxy {
Classisa;
}@interface NSObject {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
Class isaOBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}
可以看到,它遵守了 NSObject 协议,并且第一个 Ivar 是一个 isa 指针,因此它完全是可以拿来当一个 NSObject 或其派生类来使用的。
NSProxy 的使用也非常简单,通常,你只需要实现两个方法:
- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");
文章图片
image 【iOS|iOS -NSProxy】例子转自Cyandev
首先,我们需要准备一个实体类,它可以是任意一个类,甚至是系统类库所提供的类,这里我们用 NSURL 类来开刀。
@interface MyProxy : NSProxy {
id _object;
}+ (id)proxyForObject:(id)obj;
@end@implementation MyProxy+ (id)proxyForObject:(id)obj {
MyProxy *instance = [MyProxy alloc];
instance->_object = obj;
return instance;
}- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [_object methodSignatureForSelector:sel];
}- (void)forwardInvocation:(NSInvocation *)invocation {
if ([_object respondsToSelector:invocation.selector]) {
NSString *selectorName = NSStringFromSelector(invocation.selector);
NSLog(@"Before calling \"%@\".", selectorName);
[invocation invokeWithTarget:_object];
NSLog(@"After calling \"%@\".", selectorName);
}
}@end作者:Cyandev
链接:http://www.jianshu.com/p/a7187e014c03
來源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这是我们的 Proxy 简单实现,我们需要持有一个被代理对象的引用,然后将消息转发到这个对象上,在转发之前和以后我们就可以做自己想做的事情了。
methodSignatureForSelector: 方法需要获取一个方法签名,用来生成 NSInvocation,我们直接将这个调用转发到被代理对象中。紧接着,forwardInvocation: 会被调用,将 NSInvocation 用被代理对象调用。我们就可以在这个方法里做一些手脚,比如埋点计数等。在这个例子中,我只是简单地将对象所调用的方法的 selector 打印出来。
然后我们看看用于测试的主函数:
int main(int argc, char *argv[]) {
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
NSURL *url = [MyProxy proxyForObject:[NSURL URLWithString:@"https://www.google.com"]];
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
dispatch_semaphore_signal(sem);
}];
[task resume];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
return 0;
}作者:Cyandev
链接:http://www.jianshu.com/p/a7187e014c03
來源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
就是简单构造一个 NSURL,只不过我们先用了 MyProxy 封装代理后传给 NSURLSession 去使用,输出结果如下:
文章图片
image 也就是说,系统用 NSURL 的 absoluteURL 属性来获取真正的 URL 数据,至此我们就已经可以跟踪已有类的行为了,甚至还可以通过 [NSThread callStackSymbols] 来跟踪调用改方法的函数调用栈:
文章图片
image
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- iOS中的Block
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- 接口|axios接口报错-参数类型错误解决
- iOS|iOS 笔记之_时间戳 + DES 加密
- iOS,打Framework静态库
- 常用git命令总结