内存管理问题 --- NSTimer、CADisplayLink 循环引用问题
NSTimer
你如果用带Block 你可以用weak 来解决 那么下面着这种你是用weak解决不了的
- (void)viewDidLoad { [super viewDidLoad];
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerClick) userInfo:nil repeats:YES]; self.timerC = timer; }
- (void)timerClick { NSLog(@"%@",[NSThread currentThread]); } - (void)dealloc { [self.timerC invalidate]; }
当你退出控制器定时器不会被释放如何解决?
直接解释 搞一个中间类 ,直接代码
#import <Foundation/Foundation.h> @interface LSGProxy : NSObject @property (nonatomic,weak) id target;//这个weak 是关键 +(instancetype)createWithtarget:(id)target; @end #import "LSGProxy.h" @implementation LSGProxy +(instancetype)createWithtarget:(id)target{ LSGProxy *lp = [[LSGProxy alloc]init]; lp.target = target; return lp; } - (id)forwardingTargetForSelector:(SEL)aSelector { return self.target; } @end
这里讲这个中间类 import 到这个VC
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[LSGProxy createWithtarget:self] selector:@selector(timerClick) userInfo:nil repeats:YES];
这样完美解决。
CADisplayLink
同理
CADisplayLink * link = [CADisplayLink displayLinkWithTarget:[LSGProxy createWithtarget:self] selector:@selector(cadisplayLinkClcik)]; [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; self.linkC = link;
这个中间类还可以用这个类做消息转发 NSProxy , 与 有什么区别呢? NSObject 他们是同一个级别的,只是NSProxy是专门做消息转发的性能比NSObject高,也就是专业点吧下面代码展示:
@interface NSObject <NSObject> { Class isa; } @interface NSProxy <NSObject> { Class isa; }
NSProxy
@interface Proxy : NSProxy @property (nonatomic,weak) id target; +(instancetype)createWithtarget:(id)target; @end #import "Proxy.h" @implementation Proxy + (instancetype)createWithtarget:(id)target { Proxy * pr = [self alloc]; pr.target = target; return pr; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { return [self.target methodSignatureForSelector:sel]; } - (void)forwardInvocation:(NSInvocation *)invocation { [invocation invokeWithTarget:self.target]; }
效果同样