NSProxy

作者: 请叫我啊亮 | 来源:发表于2017-12-21 16:07 被阅读33次

作用一: 代理
想要拦截自定义CPTabBarController(UITabBarController子类)中tabbar的点击事件,最简单的就是直接设置自己为自己的代理self.delegate=self,再实现代理方法tabBarController:shouldSelectViewController。这样设置代理方法一看就不爽,寻求此类事件的解决方法。
NSProxy是专门为消息转发而设计的抽象类,稍微设计下就可以达到此目的。

@interface CPWeakProxy : NSProxy
+ (instancetype)proxyWithTarget:(id)target;
@end

#import "CPWeakProxy.h"
@implementation CPWeakProxy{
    __weak id _target;
}

- (instancetype)initWithTarget:(id)target {
    _target = target;
    return self;
}

+ (instancetype)proxyWithTarget:(id)target {
    return [[CPWeakProxy alloc] initWithTarget:target];
}

- (id)forwardingTargetForSelector:(SEL)selector {
    return _target;
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    return [_target respondsToSelector:aSelector];
}
@end

使用时在CPTabBarController的viewDidLoad方法中

    _proxy = [CPWeakProxy proxyWithTarget:self];
    self.delegate = _proxy;

这里必须将CPWeakProxy对象设置为控制器的属性强引用避免释放。
这里要注意的是CPWeakProxy对象必须实现respondsToSelector方法,因为UITabBarController的实现中肯定有诸如下面的代码

- (void)tabbarDidSelect{ // tabbarItem被点击时调用
    if (self.delegate && [self.delegate respondsToSelector:@selector(xxx)]) {
        [self.delegate xxx];
    }
}

CPWeakProxy是一个抽象类,respondsToSelector并未有默认实现,需要自行实现,否则会找不到方法崩溃。
tabbaritem点击时,调用代理CPWeakProxy的xxx方法,肯定找不到,触发消息转发进入CPWeakProxy的forwardingTargetForSelector方法,返回_target(就是我们自己写的CPTabBarController),调用回控制器中实现的代理方法,解决问题。

作用二:NSTimer的target
NSProxy还可以用来转发NSTimer的消息,避免NSTimer强引用控制器无法销毁。常规使用如下

 [NSTimer scheduledTimerWithTimeInterval:1 target:[CPWeakProxy proxyWithTarget:self] selector:@selector(xxx) userInfo:nil repeats:YES];

用上面方法后控制器能正常释放,但是程序崩溃了。。。

追查原因,是NSTimer会使CPWeakProxy对象无法释放,控制器销毁时没有销毁NSTimer,定时器继续回调CPWeakProxy的xxx方法,而消息转发方法forwardingTargetForSelector返回nil,转发失败程序崩溃。
结论,在控制器中NSTimer使用CPWeakProxy转发消息可以避免控制器无法销毁,但是控制器销毁时必须手动销毁定时器来保证CPWeakProxy对象正常释放。

设计的转发类继承自NSProxy而不是NSObject,是因为给NSProxy发送消息时只会在当前类中查找方法,一旦找不到就执行消息转发操作,相比NSObject少去了递归父类查找方法等流程,效率更高

相关文章

  • 重拾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

    作用一: 代理想要拦截自定义CPTabBarController(UITabBarController子类)中ta...

  • NSProxy

    它来实现一下"伪多继承". 直接上个代码来展示下 使用方法 控制台输出结果 发现没有,猫发出消息已经被子类的内部拦...

网友评论

      本文标题:NSProxy

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