延時(shí)執(zhí)行

在程序當(dāng)中經(jīng)常需要延時(shí)執(zhí)行某些操作,而常用的延時(shí)方法有四種。

performSelector方法

聲明

- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay ;

代碼舉例

[self performSelector:@selector(method:) withObject:nil afterDelay:2.0] ;

注意

  • 異步執(zhí)行,不會(huì)阻塞當(dāng)前線程鸠真。

  • 由于該方法是基于runloop的,因此必須在一個(gè)活躍的runloop中調(diào)用龄毡。主線程的runloop不會(huì)停止吠卷,因此在主線程中該方法可以正常調(diào)用;而子線程的runloop默認(rèn)是關(guān)閉的沦零,如果不手動(dòng)將其激活祭隔,該方法在子線程的調(diào)用將是無(wú)效的。

  • 在主線程中調(diào)用方法

      - (void)viewDidLoad {
          [super viewDidLoad] ;
          [self performSelector:@selector(method) withObject:nil afterDelay:2.0] ;
      }
      - (void)method {
          NSLog(@"%@",[NSThread currentThread]) ;
      }
    

打印結(jié)果為<NSThread: 0x60800007c440>{number = 1, name = main}路操,方法調(diào)用成功疾渴。

  • 在子線程中調(diào)用方法(不手動(dòng)激活)
    - (void)viewDidLoad {
        [super viewDidLoad] ;
        dispatch_async(dispatch_queue_create("test", NULL), ^{
            [self performSelector:@selector(method) withObject:nil afterDelay:2.0] ;
        }) ;
    }
    - (void)method {
        NSLog(@"%@",[NSThread currentThread]) ;
    }

無(wú)打印結(jié)果露戒,方法調(diào)用失敗峭拘。

  • 在子線程中調(diào)用方法(手動(dòng)激活)
    - (void)viewDidLoad {
        [super viewDidLoad] ;
        dispatch_async(dispatch_queue_create("test", NULL), ^{
            [self performSelector:@selector(method) withObject:nil afterDelay:2.0] ;
            [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode] ;
            [[NSRunLoop currentRunLoop] run] ;
        }) ;
    }
    - (void)method {
        NSLog(@"%@",[NSThread currentThread]) ;
    }

打印結(jié)果為<NSThread: 0x608000073e40>{number = 3, name = (null)}灭抑,方法調(diào)用成功循榆。

  • 可以通過(guò)類方法cancelPreviousPerformRequestsWithTarget:cancelPreviousPerformRequestsWithTarget:selector:object:來(lái)取消執(zhí)行,但是必須和其創(chuàng)建在同一個(gè)線程中剔氏。
  • 可以通過(guò)方法- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;確保aSelector方法會(huì)在主線程執(zhí)行。
    • wait為YES,則等待當(dāng)前線程執(zhí)行完以后主線程才會(huì)執(zhí)行aSelector方法慌核。
    • wait為NO,則不等當(dāng)前線程執(zhí)行完就在主線程中執(zhí)行aSelector方法申尼。
  • 通過(guò)該方法延時(shí)執(zhí)行aSelector方法時(shí)垮卓,最多只能傳入一個(gè)參數(shù)并且無(wú)法獲得方法的返回值。

NSTimer定時(shí)器

聲明

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

代碼舉例

 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(method:) userInfo:nil repeats:NO] ;

注意

  • 異步執(zhí)行师幕,不阻塞線程粟按。
  • 由于該方法是基于runloop的诬滩,因此必須在一個(gè)活躍的runloop中調(diào)用。主線程的runloop不會(huì)停止灭将,因此在主線程中該方法可以正常調(diào)用疼鸟;而子線程的runloop默認(rèn)是關(guān)閉的,如果不手動(dòng)將其激活庙曙,該方法在子線程的調(diào)用將是無(wú)效的空镜。
  • 在主線程中調(diào)用方法
    - (void)viewDidLoad {
        [super viewDidLoad] ;
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(method) userInfo:nil repeats:NO] ;
    }
    - (void)method {
        NSLog(@"%@",[NSThread currentThread]) ;
    }

打印結(jié)果為<NSThread: 0x600000261680>{number = 1, name = main},方法調(diào)用成功捌朴。

  • 在子線程中調(diào)用方法(不手動(dòng)激活)
    - (void)viewDidLoad {
        [super viewDidLoad] ;
        dispatch_async(dispatch_queue_create("test", NULL), ^{
             NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(method) userInfo:nil repeats:NO] ;
        }) ;
    }
    - (void)method {
        NSLog(@"%@",[NSThread currentThread]) ;
    }

無(wú)打印結(jié)果吴攒,方法調(diào)用失敗。

  • 在子線程中調(diào)用方法(手動(dòng)激活)
    - (void)viewDidLoad {
        [super viewDidLoad] ;
        dispatch_async(dispatch_queue_create("test", NULL), ^{
             NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(method) userInfo:nil repeats:NO] ;
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode] ;
            [[NSRunLoop currentRunLoop] run] ;
        }) ;
    }
    - (void)method {
        NSLog(@"%@",[NSThread currentThread]) ;
    }

打印結(jié)果為<NSThread: 0x6000002615c0>{number = 3, name = (null)}砂蔽,方法調(diào)用成功洼怔。

  • 可以通過(guò)-(void)invalidate:方法取消執(zhí)行,但是必須和其創(chuàng)建在同一個(gè)線程中左驾。
  • NSTimer定時(shí)器存在內(nèi)存泄漏的風(fēng)險(xiǎn)镣隶。通過(guò)NSTimer定時(shí)器生成的timer會(huì)被NSRunLoop對(duì)象一直持有,直到調(diào)用invalidate方法什荣。而timer又持有target對(duì)象矾缓,如果不調(diào)用invalidate方法,target對(duì)象將會(huì)一直無(wú)法被釋放稻爬,從而造成內(nèi)存泄漏嗜闻。

NSThread的sleep方法

聲明

+ (void)sleepForTimeInterval:(NSTimeInterval)ti ;

代碼舉例

[NSThread sleepForTimeInterval:2.0] ; 
[self method] ;

注意

  • 同步執(zhí)行,會(huì)阻塞線程桅锄。
  • 在主線程和子線程都可以執(zhí)行琉雳。

GCD

聲明

void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block) ;

代碼舉例

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self method] ;
});

注意

  • 異步執(zhí)行,不會(huì)阻塞線程友瘤。
  • 在主線程和子線程都可以執(zhí)行翠肘。
  • 一旦執(zhí)行就無(wú)法撤銷。
  • 系統(tǒng)會(huì)幫助處理線程級(jí)的邏輯辫秧,并且調(diào)用的對(duì)象也不會(huì)被強(qiáng)行持有束倍,這樣就不會(huì)存在內(nèi)存泄漏的問(wèn)題。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盟戏,一起剝皮案震驚了整個(gè)濱河市绪妹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柿究,老刑警劉巖邮旷,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蝇摸,居然都是意外死亡婶肩,警方通過(guò)查閱死者的電腦和手機(jī)办陷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)律歼,“玉大人民镜,你說(shuō)我怎么就攤上這事∠栈伲” “怎么了殃恒?”我有些...
    開(kāi)封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)辱揭。 經(jīng)常有香客問(wèn)我离唐,道長(zhǎng),這世上最難降的妖魔是什么问窃? 我笑而不...
    開(kāi)封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任亥鬓,我火速辦了婚禮,結(jié)果婚禮上域庇,老公的妹妹穿的比我還像新娘嵌戈。我一直安慰自己,他們只是感情好听皿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布熟呛。 她就那樣靜靜地躺著,像睡著了一般尉姨。 火紅的嫁衣襯著肌膚如雪庵朝。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天又厉,我揣著相機(jī)與錄音九府,去河邊找鬼。 笑死覆致,一個(gè)胖子當(dāng)著我的面吹牛侄旬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播煌妈,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼儡羔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了璧诵?” 一聲冷哼從身側(cè)響起汰蜘,我...
    開(kāi)封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腮猖,沒(méi)想到半個(gè)月后鉴扫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體赞枕,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澈缺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年坪创,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姐赡。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡莱预,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出项滑,到底是詐尸還是另有隱情依沮,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布枪狂,位于F島的核電站危喉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏州疾。R本人自食惡果不足惜辜限,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望严蓖。 院中可真熱鬧薄嫡,春花似錦、人聲如沸颗胡。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)毒姨。三九已至哑蔫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弧呐,已是汗流浹背鸳址。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泉懦,地道東北人稿黍。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像崩哩,于是被迫代替她去往敵國(guó)和親巡球。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容