我只是想记录一下,设置不了文章仅自己可见!!!shit!
1.NSTimer/CAD 实现分类 使用block打破引用
1.1 在分类里面实现
在初始化timer/cadlink对象的时候,指定target的时候,会保留其目标对象,其实就是这个target。在分类中,定时器对象指定的target是timer/cadlink的类对象,这是个单例对象,因此计时器的是否保留他无所谓,因为类对象无需回收。
2. YYWeakProxy等
NSproxy本身是一个抽象类,他遵循NSObject协议,提供了消息转发的接口。NSProxy通常来实现消息转发和懒加载初始化资源。但,需要创建NSProxy的子类,实现init以及消息转发的相关方法,才可以用。
YYWeakProxy继承了NSProxy,定义了一个弱引用的target对象,重写消息转发,让target对象去处理接收到的消息,等于让原来ViewController对象去直接处理但这里拐了一个弯,在这个弯里用弱引用解除了timer和controller的本来的强引用。
引用链 以下用——代表强引用 ,用---代表弱应用
Controller——>NSTime/CADisplayLink——>YYWeakProxy--->Controller
代码
// NSTimer+QSTool.h
typedef void(^QSExecuteTimerBlock) (NSTimer *timer);
@interface NSTimer (QSTool)
+ (NSTimer *)qs_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval executeBlock:(QSExecuteTimerBlock)block repeats:(BOOL)repeats;
@end
// NSTimer+QSTool.m
@implementation NSTimer (QSTool)
+ (NSTimer *)qs_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval executeBlock:(QSExecuteTimerBlock)block repeats:(BOOL)repeats{
NSTimer *timer = [self scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(qs_executeTimer:) userInfo:[block copy] repeats:repeats];
return timer;
}
+ (void)qs_executeTimer:(NSTimer *)timer{
QSExecuteTimerBlock block = timer.userInfo;
if (block) {
block(timer);
}
}
@end
// CADisplayLink+QSTool.h
@class CADisplayLink;
typedef void(^QSExecuteDisplayLinkBlock) (CADisplayLink *displayLink);
@interface CADisplayLink (QSTool)
@property (nonatomic,copy)QSExecuteDisplayLinkBlock executeBlock;
+ (CADisplayLink *)displayLinkWithExecuteBlock:(QSExecuteDisplayLinkBlock)block;
@end
// CADisplayLink+QSTool.m
@implementation CADisplayLink (QSTool)
- (void)setExecuteBlock:(QSExecuteDisplayLinkBlock)executeBlock{
objc_setAssociatedObject(self, @selector(executeBlock), [executeBlock copy], OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (QSExecuteDisplayLinkBlock)executeBlock{
return objc_getAssociatedObject(self, @selector(executeBlock));
}
+ (CADisplayLink *)displayLinkWithExecuteBlock:(QSExecuteDisplayLinkBlock)block{
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(qs_executeDisplayLink:)];
displayLink.executeBlock = [block copy];
return displayLink;
}
+ (void)qs_executeDisplayLink:(CADisplayLink *)displayLink{
if (displayLink.executeBlock) {
displayLink.executeBlock(displayLink);
}
}
@end
1.使用category分类
- (void)viewDidLoad {
[super viewDidLoad];
// ...
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer qs_scheduledTimerWithTimeInterval:timeInterval executeBlock:^(NSTimer *timer) {
__weak typeof(weakSelf) strongSelf = weakSelf;
[strongSelf executeTimer:timer];
} repeats:YES];
[self.timer fire];
//...
}
- (void)executeTimer:(NSTimer *)timer{
//do something
}
- (void)dealloc{
[self.timer invalidate];
}
2.使用yyweakproxy
- (void)viewDidLoad {
[super viewDidLoad];
// ...
self.displayLink = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(executeDispalyLink:)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
//...
}
- (void)executeDispalyLink:(CADisplayLink *)displayLink{
//...
}
- (void)dealloc{
[self.displayLink invalidate];
}