CADisplayLink使用中的循环引用问题的解决
解决循环引用的问题,参考学习了ibireme大神的YYFPSLabel的实现,整理以备用
// 如果直接用 self 或者 weakSelf,都不能解决循环引用问题 _link = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(tick:)]; // _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)]; // __weak typeof(self) weakSelf = self; // _link = [CADisplayLink displayLinkWithTarget:weakSelf selector:@selector(tick:)]; [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; //NSDefaultRunLoopMode - 标准优先级 //NSRunLoopCommonModes - 高优先级 //UITrackingRunLoopMode - 用于UIScrollView和别的控件的动画 return self;
@interface YYWeakProxy : NSProxy /** The proxy target. */ @property (nonatomic, weak, readonly) id target; /** Creates a new weak proxy for target. @param target Target object. @return A new proxy object. */ - (instancetype)initWithTarget:(id)target; /** Creates a new weak proxy for target. @param target Target object. @return A new proxy object. */ + (instancetype)proxyWithTarget:(id)target; @end
@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( /BrE ˈprɒksi/)的父类不是NSObject