美文网首页
iOS -NSProxy

iOS -NSProxy

作者: linbj | 来源:发表于2017-12-15 11:44 被阅读416次
@interface NSProxy <NSObject> {
    Class   isa;
}

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_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

例子转自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

相关文章

  • NSProxy

    NSProxy——少见却神奇的类 - IOS - 伯乐在线

  • iOS NSProxy

    NSProxy类在分布式对象架构中是很重要的。由于作用比较特别,NSProxy在Cocoa程序中出现频率很低。 N...

  • iOS -NSProxy

    可以看到,它遵守了 NSObject 协议,并且第一个 Ivar 是一个 isa 指针,因此它完全是可以拿来当一个...

  • iOS | NSProxy

    Objective-C作为一种动态消息型语言,其机制不同于Java ,C#等编译型语言.它将数据类型的确定等工作...

  • iOS:NSProxy

    OC 中一个类只有一个父类,这就是单一继承,但是我们可以用协议和NSProxy实现多继承。 1、 protocol...

  • iOS NSProxy

    NSProxy是一个实现了NSObject协议的根类。 苹果的官方文档是这样描述的:NSProxy 是一个抽象基类...

  • iOS 解决NSTimer的循环引用问题

    iOS 13以后可以通过block解决target的强引用问题,如果程序兼顾iOS13以下,那么使用NSProxy...

  • iOS NSProxy探究

    什么是NSProxy NSProxy是和NSObject同级的一个类,可以说它是一个虚拟类,它只是实现了

  • ios开发-NSProxy

    作用:与NSObject属同一个级别,负责将消息转发到真正的target的代理类,实现类似于多继承的功能。 打个比...

  • iOS NSProxy使用

    简介:通过NSProxy 可以实现类的"伪多继承",demo中KLProxy通过拦截方法修改了cat和dog本来的...

网友评论

      本文标题:iOS -NSProxy

      本文链接:https://www.haomeiwen.com/subject/gvprwxtx.html