`_timer = [nstimer scheduledtimerwithtimeinterval:1.0 target:self selector:@selector(countdown) userinfo:nil repeats:yes];`
定義乙個@property (nonatomic,strong) nstimer *timer;
第一種方法如下所示:
@inte***ce nstimer (jqusingblock)
+ (nstimer *)jq_scheduledtimerwithtimeinterval:(nstimeinterval)ti
block:(void(^)())block
repeats:(bool)repeats;
@end
@implementation nstimer (jqusingblock)
+ (nstimer *)lsz_scheduledtimerwithtimeinterval:(nstimeinterval)ti
block:(void(^)())block
repeats:(bool)repeats
+ (void)jq_blockinvoke:(nstimer *)timer
}@end
nstimer
的類別,在類別中定義乙個類方法。類方法有乙個型別為塊的引數(定義的塊位於棧上,為了防止塊被釋放,需要呼叫copy
方法,將塊移到堆上)。使用這個類別的方式如下:
__weak viewcontroller *weakself = self;
_timer = [nstimer lsz_scheduledtimerwithtimeinterval:1.0
block:^
repeats:yes];
使用這種方案就可以防止nstimer
對類的保留,從而打破了迴圈引用的產生。__strong viewcontroller *strongself = weakself
主要是為了防止執行塊的**時,類被釋放了。在類的dealloc
方法中,記得呼叫[_timer invalidate]
。
nsproxy本身是乙個抽象類,它遵循nsobject協議,提供了訊息**的通用介面。nsproxy通常用來實現訊息**機制和惰性初始化資源。
使用nsproxy,你需要寫乙個子類繼承它,然後需要實現init以及訊息**的相關方法。
1 //當乙個訊息**的動作nsinvocation到來的時候,在這裡選擇把訊息**給對應的實際處理物件訊息**涉及到三個核心方法2 - (void)forwardinvocation:(nsinvocation *)aninvocation
3 4 //當乙個sel到來的時候,在這裡返回sel對應的nsmethodsignature
5 - (nsmethodsignature *)methodsignatureforselector:(sel)aselector
6 7 //是否響應乙個sel
8 + (bool)respondstoselector:(sel)aselector
1 //訊息**第一步,在這裡可以動態的為類新增方法,這樣類自己就能處理了訊息**機制使得**變的很靈活:乙個類本身可以完全不實現某些方法,它只要能**就可以了。2 +resolveinstancemethod:
3 //訊息**第二步,在第一步無法完成的情況下執行。這裡只是把乙個selector簡單的**給另乙個物件
4 - forwardingtargetforselector:
5 //訊息**第三步,在第二步也無法完成的情況下執行。將整個訊息封裝成nsinvocation,傳遞下去
6 - forwardinvocation:
@inte***ce weakproxy : nsproxy外部建立timer@property (weak,nonatomic,readonly)id target;
+ (instancetype)proxywithtarget:(id)target;
- (instancetype)initwithtarget:(id)target;
@end
@implementation weakproxy
- (instancetype)initwithtarget:(id)target
+ (instancetype)proxywithtarget:(id)target
- (void)forwardinvocation:(nsinvocation *)invocation
}- (nsmethodsignature *)methodsignatureforselector:(sel)aselector
- (bool)respondstoselector:(sel)aselector
@end
self.timer = [nstimer timerwithtimeinterval:1原理如下:target:[weakproxy proxywithtarget:self]
selector:@selector(timerinvoked:)
userinfo:nil
repeats:yes];
我們把虛線處變成了弱引用。於是,controller就可以被釋放掉,我們在controller的dealloc中呼叫invalidate
,就斷掉了runloop對timer的引用,於是整個三個淡藍色的就都被釋放掉了。
__weak subviewcontroller *weakself = self;
_timer = [nstimer scheduledtimerwithtimeinterval:1.0 repeats:yes block:^(nstimer * _nonnull timer) ];
ios10以後出現了乙個新的方法不需要傳入self,在block裡迴圈執行就可以 NSTimer中的迴圈引用
void viewdidload void p dosomething void p stopdosomething void dealloc 上面的 主要是利用定時器重複執行p dosomething方法,在合適的時候呼叫p stopdosomething方法使定時器失效.scheduledtim...
iOS中解決NSTimer迴圈引用的三種方式
今天有個人來公司面試,問了他平時在使用timer定時器時怎麼解決迴圈引用的問題。然後就得到了這樣乙個答案 weak typeof self weakself self self.timer nstimer scheduledtimerwithtimeinterval 1.0 target weaks...
迴圈引用問題
main.m 07 迴圈引用 created by kevin on 13 8 9.1.class的作用 僅僅告訴編譯器,某個名稱是乙個類 class person 僅僅告訴編譯器,person是乙個類 2.開發中引用乙個類的規範 1 在.h檔案中用 class來宣告類 2 在.m檔案中用 impo...