我只是想記錄一下,設(shè)置不了文章僅自己可見?。。hit!
1.NSTimer/CAD 實現(xiàn)分類 使用block打破引用
1.1 在分類里面實現(xiàn)
在初始化timer/cadlink對象的時候,指定target的時候,會保留其目標對象,其實就是這個target。在分類中,定時器對象指定的target是timer/cadlink的類對象,這是個單例對象,因此計時器的是否保留他無所謂,因為類對象無需回收。
2. YYWeakProxy等
NSproxy本身是一個抽象類,他遵循NSObject協(xié)議,提供了消息轉(zhuǎn)發(fā)的接口。NSProxy通常來實現(xiàn)消息轉(zhuǎn)發(fā)和懶加載初始化資源。但,需要創(chuàng)建NSProxy的子類,實現(xiàn)init以及消息轉(zhuǎn)發(fā)的相關(guān)方法,才可以用。
YYWeakProxy繼承了NSProxy,定義了一個弱引用的target對象,重寫消息轉(zhuǎn)發(fā),讓target對象去處理接收到的消息,等于讓原來ViewController對象去直接處理但這里拐了一個彎,在這個彎里用弱引用解除了timer和controller的本來的強引用。
引用鏈 以下用——代表強引用 ,用---代表弱應(yīng)用
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];
}