一恋拷、初始化
(1)+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
(2)+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;
(3)+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
(4)+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
(5)- (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep
注意:這五種初始化方法的異同:
1资厉、參數(shù)repeats是指定是否循環(huán)執(zhí)行,YES將循環(huán)蔬顾,NO將只執(zhí)行一次宴偿。
2、timerWithTimeInterval(1)&(3)這兩個(gè)類方法創(chuàng)建出來的對象如果不用 addTimer: forMode方法手動(dòng)加入主循環(huán)池中诀豁,將不會(huì)循環(huán)執(zhí)行窄刘。并且如果不手動(dòng)調(diào)用fire,則定時(shí)器不會(huì)啟動(dòng)且叁。
3都哭、scheduledTimerWithTimeInterval(2)&(4)這兩個(gè)方法不需要手動(dòng)調(diào)用fire,會(huì)自動(dòng)執(zhí)行逞带,并且自動(dòng)加入主循環(huán)池欺矫。
4、init(5)方法需要手動(dòng)加入循環(huán)池展氓,它會(huì)在設(shè)定的啟動(dòng)時(shí)間啟動(dòng)穆趴。
二、成員變量
@property (copy) NSDate *fireDate;
@property (readonly) NSTimeInterval timeInterval;
這個(gè)是一個(gè)只讀屬性遇汞,獲取定時(shí)器調(diào)用間隔時(shí)間未妹。
@property NSTimeInterval tolerance;
這是7.0之后新增的一個(gè)屬性簿废,因?yàn)镹STimer并不完全精準(zhǔn),通過這個(gè)值設(shè)置誤差范圍络它。
@property (readonly, getter=isValid) BOOL valid;
獲取定時(shí)器是否有效
@property (readonly, retain) id userInfo;
獲取參數(shù)信息
三族檬、關(guān)于內(nèi)存釋放
如果我們啟動(dòng)了一個(gè)定時(shí)器,在某個(gè)界面釋放前化戳,將這個(gè)定時(shí)器停止单料,甚至置為nil,都不能是這個(gè)界面釋放点楼,原因是系統(tǒng)的循環(huán)池中還保有這個(gè)對象扫尖。所以我們需要這樣做:
在官方文檔中我們可以看到 [timer invalidate]是唯一的方法將定時(shí)器從循環(huán)池中移除。
四掠廓、關(guān)于NSInvocation
IOS中有一個(gè)類型是SEL,它的作用很相似與函數(shù)指針沉颂,通過 performSelector:withObject:函數(shù)可以直接調(diào)用這個(gè)消息悦污。但是perform相關(guān)的這些函數(shù),有一個(gè)局限性,其參數(shù)數(shù)量不能超過2個(gè)子巾,否則要做很麻煩的處理线梗,與之相對,NSInvocation也是一種消息調(diào)用的方法瘾婿,并且它的參數(shù)沒有限制烤咧。這兩種直接調(diào)用對象消息的方法,在IOS4.0之后笛谦,大多被block結(jié)構(gòu)所取代饥脑,只有在很老的兼容性系統(tǒng)中才會(huì)使用,簡單用法總結(jié)如下:
1灶轰、初始化與調(diào)用
在官方文檔中有明確說明,NSInvocation對象只能使用其類方法來初始化乳附,不可使用alloc/init方法许溅。它執(zhí)行調(diào)用之前秉版,需要設(shè)置兩個(gè)方法:setSelector: 和setArgument:atIndex:
注意:簽名函數(shù)的參數(shù)數(shù)量要和調(diào)用函數(shù)的一致清焕。測試后發(fā)現(xiàn),當(dāng)簽名函數(shù)參數(shù)數(shù)量大于被調(diào)函數(shù)時(shí)滚停,也是沒有問題的键畴。
注意:(1)突雪、這里設(shè)置參數(shù)的Index 需要從2開始咏删,因?yàn)榍皟蓚€(gè)被selector和target占用。下面這樣寫也沒有任何問題:
(2)嘀粱、這里的傳參方式必須是傳遞參數(shù)地址锋叨。
2宛篇、NSInvocation的返回值
NSInvocation對象,是可以有返回值的豌鸡,然而這個(gè)返回值,并不是其所調(diào)用函數(shù)的返回值炉奴,需要我們手動(dòng)設(shè)置:
注意:這里的操作傳遞的都是地址瞻赶。如果是OC對象派任,也是取地址。
3师逸、關(guān)于內(nèi)存
可以注意到- (void)retainArguments;這個(gè)方法篓像,它會(huì)將傳入的所有參數(shù)以及target都retain一遍皿伺。