国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

那些年我們踩過的坑-NSTimer

2019-11-14 20:07:04
字體:
來源:轉載
供稿:網友

  昨天下午工作的時候遇見一個這樣的需求,網絡請求失敗后把請求數據保存到本地,并自動重發3次,時間間隔是10秒,如果3次后還失敗的話,下一次啟動這個接口的時候,把新數據和保存在本地的數據都要發送,剛開始以為沒多少難度,不就是網絡請求發送數據嘛,首先腦子里的第一反應就是用定時器,初始化定時器,然后觸發相應的方法,設置請求的次數標志,超過3次停止定時器。事實卻證明我還沒有理解定時器......

  由于是老接口,不能修改,因為產品已經上線,修改會涉及到太多業務,所以只能客戶端想辦法處理。這樣導致的問題就是新數據不能和舊數據一起整合在一起發送,得分兩次發送。好吧,那就上吧,我就信心滿滿的上了。

     初始化定時器,遍歷本地的數據,分別對應創建一個定時器使用下面的方法,加載到定時器數組

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

然后fire執行。OK,搞定。

bi..bi...bi...bi....bi.....bi......

  擦,定時器全亂了,10s內定時器沒啥問題,10s后所以定時器都交替進行。。。這不是坑爹么。。。。

  吸了口氣,喝了一杯水,掃了一眼定時器的代碼,靈光一閃,會不會是fire用錯了,初始化的時候不要立即執行,等初始化完畢的時候在從數組里面拿出定時器,請求成功或者失敗三次后再拿出第二個定時器請求。哈哈哈哈哈哈,應該不會錯了,就這么辦。

bi....bi.....bi.....bi....bi........

  我了個去,稍微好一點了,20秒內的數據是正常的,后面的定時器又交替進行。。。。泥煤呀,甘都得。。。不過已經有進步了,至少20秒是正確的吧,再改改代碼應該就可以了,所以立馬想一下定時器的執行流程,后來發現會不會是多個定時器和一個定時器的運行是有區別的?因為自己之前基本上都是創建一個定時器就可以了,fire、invalidate使用。沒辦法,上SOF看看吧。后來才知道原來這兩個方法初始化的定時器即使不用fire也會對應的NSTimeInterval后執行,fire只是讓他們立即執行,把啟動的時間提前到當前,就像一個演唱會本來打算10分鐘后開始的,現在因為主唱提前10分鐘到了會場,看見粉絲這么熱情,提前開始了。

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

  可是問題又來了,那既然這樣沒辦法控制定時器的執行,我這個功能豈不是沒法做了,有沒有什么辦法可以控制定時器么,想執行的時候就執行,不想執行的時候就丟掉它。。。。

  查找資料的過程中還發現了幾個初始化定時器的方法:兩個類方法,一個實例方法。

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;- (id)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(id)ui repeats:(BOOL)rep;

  這和上面的初始化方法有什么區別么,接著發現者兩個類方法和實例方法是要手動添加到NSRunLoop代碼執行的:

[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];

哈哈哈,這不就是我想要的東東嘛(ˇ?ˇ),yo yo check now!

修改定時器的方法,手動添加NSRunLoop執行,然后網絡請求不變。。。。OK,搞定。。

bi..bi.....bi....bi......

無壓力了。。。。測試一個for循環1000次,沒發生什么錯誤。。。好吧,來個總結。

一直都習慣用最上面的兩個方法初始化定時器,然后fire,并且fire的作用只是把定時器的時間提前了,這個是之前使用的時候沒有去考慮的。。這種東東在一個定時器下面不會有什么問題,但是多個定時器的話基本上就悲劇。。不過在同一個地方使用多個定時器這樣的設計方法我暫時也不知道合理不合理,可能也會有意想不到的的錯誤,比如內存暴漲,性能受影響之類的,這個暫時沒有去考慮,如果你有更好的解決方法,可以交流交流。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宝兴县| 曲靖市| 绥中县| 温泉县| 剑川县| 札达县| 长乐市| 鄂伦春自治旗| 林芝县| 慈利县| 营山县| 巴南区| 富裕县| 余江县| 搜索| 德令哈市| 江孜县| 玉山县| 潜山县| 门头沟区| 邮箱| 铁岭市| 徐闻县| 金平| 延津县| 南溪县| 萨嘎县| 新津县| 招远市| 余江县| 古交市| 绩溪县| 英吉沙县| 南宫市| 绥阳县| 枞阳县| 分宜县| 仙桃市| 巩义市| 分宜县| 巴林右旗|