首先,了解下NSTimer的循环引用
@interface ViewController ()
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(testForTimer)
userInfo:nil
repeats:YES];
}
- (void)testForTimer {
NSLog(@"%s",__func__);
}
@end
循环引用:
mage
__weak
来修饰self
从而达到targe
t指向ViewController
是弱引用的效果。target
,target
还是强引用viewController
地址。我们用的weak是处理block的循环引用,block中会把__weak
修饰的对象 描述为弱引用@interface SRProxy : NSProxy
@property (nonatomic, weak) id target;
+ (instancetype)proxyWithTarget:(id)target;
@end
@implementation SRProxy
+ (instancetype)proxyWithTarget:(id)target {
SRProxy *proxy = [SRProxy alloc];
proxy.target = target;
return proxy;
}
- (id)forwardingTargetForSelector:(SEL)aSelector {
if (self.target) {
return self.target;
}
return self;
}
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [self.target methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
@end
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:[SRProxy proxyWithTarget:self] selector:@selector(testForTimer) userInfo:nil repeats:YES];
@interface NSProxy <NSObject> {
Class isa;
}
NSProxy为基类,和NSObject同级, 专门处理这种代理实现事件。
SRProxy继承于NSProxy 如果继承NSObject 也可以实现功能。
继承于NSProxy的类 找实现方法的时候 只会找当前类是否实现 而不找super,如果没找到直接进入消息动态解析,以及消息转发机制。比继承NSObject的类少了找super,从而效率更高。
如果把SRProxy中的消息转发机制去掉 看一下错误信息
NSProxy没有init方法 只要alloc 既可
当我们继承于NSProxy 在上述ViewDidLoad
中打印此代码 结果为
NSLog(@"isKindOfClass == %d",[[SRProxy proxyWithTarget:self] isKindOfClass:[self class]]);
调用isKindOfClass
进行消息转发 走的是下面的方法
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [self.target methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
实际调用的是self.target
去执行objc_msgSend(self.target,SEL)
所以为1
isKindOfClass 为1