浅谈NSProxy

作者: _涼城 | 来源:发表于2022-04-07 09:27 被阅读0次

什么是 NSProxy

    在苹果官方文档中是这样对 NSProxy 描述的:一个抽象的根类,通常,发送给代理的消息被转发到真实对象,或使代理加载(或转换为)真实对象。头文件代码如下:

@interface NSProxy <NSObject> {
    __ptrauth_objc_isa_pointer Class isa;
}

+ (id)alloc;
+ (id)allocWithZone:(nullable NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (Class)class;

- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");
- (void)dealloc;
- (void)finalize;
@property (readonly, copy) NSString *description;
@property (readonly, copy) NSString *debugDescription;
+ (BOOL)respondsToSelector:(SEL)aSelector;

- (BOOL)allowsWeakReference API_UNAVAILABLE(macos, ios, watchos, tvos);
- (BOOL)retainWeakReference API_UNAVAILABLE(macos, ios, watchos, tvos);

// - (id)forwardingTargetForSelector:(SEL)aSelector;

@end

NSProxy 使用

    可以看到 NSProxy 是一个实现了 <NSObject> 协议的根类,NSProxy 实现根类所需的基本方法,包括 <NSObject> 协议中定义的方法。然而,作为一个抽象类,它不提供初始化方法,并且在收到任何未响应的消息时引发异常。因此,

  1. 一个具体的子类必须提供一个初始化或创建方法,
  2. 并重写 forwardInvocation:methodSignatureForSelector: 方法来处理它自己没有实现的消息。
    • forwardInvocation 的子类实现:应该执行处理调用所需的任何操作,例如通过网络转发调用或加载真实对象并将调用传递给它。
    • methodSignatureForSelector: 需要提供给定消息的参数类型信息;子类的实现应该能够确定它需要转发的消息的参数类型,并且应该相应地构造一个 NSMethodSignature 对象。

中介者

    使用 NSProxytarget 进行消息转发,并不会对 target 造成引用关系。 A ->NSProxy -> B 。例如,YYKit/YYWeakProxy,源码如下:

  • YYWeakProxy.h

    
    /**
     A proxy used to hold a weak object.
     It can be used to avoid retain cycles, such as the target in NSTimer or CADisplayLink.
     
     sample code:
     
         @implementation MyView {
            NSTimer *_timer;
         }
         
         - (void)initTimer {
            YYWeakProxy *proxy = [YYWeakProxy proxyWithTarget:self];
            _timer = [NSTimer timerWithTimeInterval:0.1 target:proxy selector:@selector(tick:) userInfo:nil repeats:YES];
         }
         
         - (void)tick:(NSTimer *)timer {...}
         @end
     */
    @interface YYWeakProxy : NSProxy
    
    /**
     The proxy target.
     */
    @property (nullable, nonatomic, weak, readonly) id target;
    - (instancetype)initWithTarget:(id)target;
    + (instancetype)proxyWithTarget:(id)target;
    
    @end
    
  • YYWeakProxy.m

    #import "YYWeakProxy.h"
    
    
    @implementation YYWeakProxy
    
    - (instancetype)initWithTarget:(id)target {
        _target = target;
        return self;
    }
    
    + (instancetype)proxyWithTarget:(id)target {
        return [[YYWeakProxy alloc] initWithTarget:target];
    }
    
    - (id)forwardingTargetForSelector:(SEL)selector {
        return _target;
    }
    
    - (void)forwardInvocation:(NSInvocation *)invocation {
        void *null = NULL;
        [invocation setReturnValue:&null];
    }
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
        return [NSObject instanceMethodSignatureForSelector:@selector(init)];
    }
    
    - (BOOL)respondsToSelector:(SEL)aSelector {
        return [_target respondsToSelector:aSelector];
    }
    
    - (BOOL)isEqual:(id)object {
        return [_target isEqual:object];
    }
    
    - (NSUInteger)hash {
        return [_target hash];
    }
    
    - (Class)superclass {
        return [_target superclass];
    }
    
    - (Class)class {
        return [_target class];
    }
    
    - (BOOL)isKindOfClass:(Class)aClass {
        return [_target isKindOfClass:aClass];
    }
    
    - (BOOL)isMemberOfClass:(Class)aClass {
        return [_target isMemberOfClass:aClass];
    }
    
    - (BOOL)conformsToProtocol:(Protocol *)aProtocol {
        return [_target conformsToProtocol:aProtocol];
    }
    
    - (BOOL)isProxy {
        return YES;
    }
    
    - (NSString *)description {
        return [_target description];
    }
    
    - (NSString *)debugDescription {
        return [_target debugDescription];
    }
    
    @end
    

多继承

    NSProxy 能对多个对象方法进行转发,就使得 NSProxy 具有了多个对象的方法,可以实现“多继承”。

相关文章

  • 浅谈NSProxy

    在项目优化中突然发现了NSTimer和CADisplayLink 在runloop的驱动下会有的时候出现内存无法释...

  • 浅谈NSProxy

    什么是 NSProxy 在苹果官方文档中是这样对 NSProxy 描述的:一个抽象的根类,通常,发送给代理的消息被...

  • 重拾iOS-NSProxy

    关键词:NSProxy,NSObject,Runtime 面试题:1)知道NSProxy吗?2)NSProxy和N...

  • NSProxy

    NSProxy.h文件内容 NSProxy 是一个抽象类NSProxy遵守了 NSObject 协议,内部有它的 ...

  • NSProxy、NSInvocation、NSMethodSig

    什么是NSProxy: NSProxy是一个抽象的基类,是根类,与NSObject类似 NSProxy和NSObj...

  • [iOS] 七七八八的小姿势(2)

    目录: NSProxy 字典集合对成员的引用方式 class判断 block变量捕获 1. NSProxy NSP...

  • NSProxy 和 NSObject 关系

    一、NSProxy 简介NSProxy 是一个抽象类,它实现了protocol NSObject 所要求的基本方法...

  • 老生常谈之NSProxy和NSTimer

    网上NSProxy和NSTimer都写烂了,所以这里只做下总结: 1.NSProxy应用场景: 解决NSTimer...

  • NSProxy

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

  • NSProxy

    吾尝以为NSObject是Apple的所有Objective-C引用类型的老祖宗,直到后来知道了NSProxy的存...

网友评论

    本文标题:浅谈NSProxy

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