RunLoop在實(shí)際開(kāi)發(fā)過(guò)程中的應(yīng)用(二)

Tip

  • 1.UIImageView延遲加載照片
  • 2.線程保活
  • 3.子線程中執(zhí)行NSTimer
  • 4.performSelector
  • 5.自動(dòng)釋放池
一.UIImageView延遲加載照片

在實(shí)際的開(kāi)發(fā)過(guò)程中和面試題中,我們總?cè)フf(shuō)可以在tableview的滑動(dòng)的時(shí)候不去加載照片尤蒿,因?yàn)殇秩究赡軙?huì)阻塞主線程教馆,我們總說(shuō):可以再tableview停止滑動(dòng)的時(shí)候再去渲染照片,現(xiàn)在可以好好聊聊這個(gè)話題

//控制中寫(xiě)上這個(gè)方法即可,3秒鐘然后顯示照片
//這個(gè)方法,我看就可以在滑動(dòng)的時(shí)候,延遲顯示照片
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.imageview performSelector:@selector(setImage:)
                         withObject:[UIImage imageNamed:@"123.png"]
                         afterDelay:3];
}

//這個(gè)是第二種清空颅崩,然后直接指定什么模式,二者等價(jià)
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.imageview performSelector:@selector(setImage:)
                         withObject:[UIImage imageNamed:@"123.png"]
                         afterDelay:3
     inModes:@[NSDefaultRunLoopMode]];
}

滑動(dòng)的時(shí)候蕊苗,阻止了照片顯示沿后,因?yàn)樗J(rèn)是在Default下顯示, 此時(shí)tableView在滑動(dòng)朽砰,RunLoop屬于Tracking的模式尖滚, 所以3秒鐘顯示的目的被延時(shí)了
  • 如果想讓照片的顯示或者timer的運(yùn)行在任何時(shí)候都好使怎么辦?
    設(shè)置為commonMode就行了
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self.imageview performSelector:@selector(setImage:)
                         withObject:[UIImage imageNamed:@"123.png"]
                         afterDelay:3
     inModes:@[NSRunLoopCommonModes]];
}
二.線程鼻迫幔活

可能你的項(xiàng)目中需要一個(gè)線程漆弄,一直在后臺(tái)做些耗時(shí)操作,但是不影響主線程造锅,我們不要一直大量的創(chuàng)建和銷毀線程撼唾,因?yàn)檫@樣太浪費(fèi)性能了,我們只要保留這個(gè)線程哥蔚,只要對(duì)他進(jìn)行“钡构龋活”就行

//繼承了一個(gè)NSTread 線程蛛蒙,然后使用vc中創(chuàng)建和執(zhí)行某個(gè)任務(wù),查看線程的情況
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    WXThread *thread = [[WXThread alloc] initWithTarget:self
                                               selector:@selector(doSomeThing)
                                                 object:nil];
    [thread start];
}
- (void)doSomeThing{
    NSLog(@"doSomeThing");
}
//每一次點(diǎn)擊屏幕的時(shí)候恨锚,線程執(zhí)行完方法宇驾,直接釋放掉了,下一次創(chuàng)建了一個(gè)新的線程猴伶;
//子線程存活的時(shí)間很短,只要執(zhí)行完畢任務(wù)塌西,就會(huì)被釋放
2017-04-19 16:03:10.686 WXAllTest[14928:325108] doSomeThing
2017-04-19 16:03:10.688 WXAllTest[14928:325108] WXTread - dealloc - <WXThread: 0x600000276780>{number = 3, name = (null)}
2017-04-19 16:03:18.247 WXAllTest[14928:325194] doSomeThing
2017-04-19 16:03:18.249 WXAllTest[14928:325194] WXTread - dealloc - <WXThread: 0x608000271340>{number = 4, name = (null)}
2017-04-19 16:03:23.780 WXAllTest[14928:325236] doSomeThing
2017-04-19 16:03:23.781 WXAllTest[14928:325236] WXTread - dealloc - <WXThread: 0x608000270e00>{number = 5, name = (null)}

如果我每隔一段時(shí)間就像在線程中執(zhí)行某個(gè)操作他挎,好像現(xiàn)在不行
如果我們將線程對(duì)象強(qiáng)引用,也是不行的捡需,會(huì)崩潰

1.成為基本屬性
/** 線程對(duì)象 */
@property(strong,nonatomic)  WXThread *thread;

2.創(chuàng)建線程之后办桨,直接將入到RunLoop中
- (void)viewDidLoad {
    [super viewDidLoad];
    _thread = [[WXThread alloc] initWithTarget:self
                                      selector:@selector(doSomeThing)
                                        object:nil];
    [_thread start];
}

3.執(zhí)行doSomeThing函數(shù)
- (void)doSomeThing{
    //一定要加入一個(gè)timer,port站辉,或者是obervers呢撞,否則RunLoop啟動(dòng)不起來(lái)
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
}

4.在點(diǎn)擊屏幕的時(shí)候,執(zhí)行一個(gè)方法饰剥,線程之間的數(shù)據(jù)通信

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self performSelector:@selector(test) onThread:_thread withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
}

5.將test方法寫(xiě)清楚
- (void)test{
    NSLog(@"current thread - %@",[NSThread currentThread]);
}


//打印結(jié)果:同一個(gè)線程殊霞,線程保活成功
2017-04-19 18:21:07.660 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
2017-04-19 18:21:07.843 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
2017-04-19 18:21:08.015 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
2017-04-19 18:21:08.194 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
2017-04-19 18:21:08.398 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
2017-04-19 18:21:08.598 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
2017-04-19 18:21:08.770 WXAllTest[16145:382366] current thread - <WXThread: 0x60800007c180>{number = 3, name = (null)}
三.子線程中執(zhí)行NSTimer

剛才學(xué)習(xí)了在RunLoop中去處理源,source (seletor)汰蓉,現(xiàn)在來(lái)看看如何在子線程中處理NSTimer

/** 線程對(duì)象 */
@property(strong,nonatomic)  WXThread *thread;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //延遲圖片加載
    
    _thread = [[WXThread alloc] initWithTarget:self
                                      selector:@selector(execute)
                                        object:nil];
    [_thread start];
}

- (void)execute{
    //該方法默認(rèn)不加入RunLoop中绷蹲,使用schedule可以
    NSTimer *timer = [NSTimer timerWithTimeInterval:0.3
                                             target:self
                                           selector:@selector(test2)
                                           userInfo:nil
                                            repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
}

- (void)test2{
    NSLog(@"current thread ********** 2 - %@",[NSThread currentThread]);
}

//打印:
2017-04-19 18:45:18.342 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:18.643 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:18.943 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:19.243 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:19.544 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:19.842 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:20.143 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:20.443 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:20.743 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:21.042 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}
2017-04-19 18:45:21.342 WXAllTest[16508:398383] current thread ********** 2 - <WXThread: 0x608000261380>{number = 3, name = (null)}

注意: 這兩者相同,后者默認(rèn)直接創(chuàng)建了RunLoop顾孽,然后加進(jìn)去了祝钢,但是一定要run才能啟動(dòng),但是過(guò)去我們沒(méi)有在主線程中run若厚,也好使啊拦英,為毛?因?yàn)樵谥骶€程中系統(tǒng)自動(dòng)run了,否則線程早就停止了

    NSTimer *timer = [NSTimer timerWithTimeInterval:0.3
                                             target:self
                                           selector:@selector(test2)
                                           userInfo:nil
                                            repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
    [NSTimer scheduledTimerWithTimeInterval:1
                                                      target:self
                                                    selector:@selector(test2)
                                                    userInfo:nil
                                                     repeats:YES];
    [[NSRunLoop currentRunLoop] run];

疑惑:滑動(dòng)textview的時(shí)候测秸,模式已經(jīng)改成了Tracking,但是我們的timer是default模式疤估,為什么沒(méi)有影響?

因?yàn)閠extView是主線程的乞封,而timer是子線程的東西做裙,所以沒(méi)關(guān)系

五.自動(dòng)釋放池

1.什么是自動(dòng)釋放池,就是將目前使用到的對(duì)象放到池子中肃晚,然后當(dāng)自動(dòng)釋放池銷毀的時(shí)候锚贱,對(duì)內(nèi)部的所有對(duì)象都進(jìn)行realese操作,retrainCount減一
2.自動(dòng)釋放池什么時(shí)候銷毀和創(chuàng)建关串?
當(dāng)每一次要進(jìn)入睡眠狀態(tài)拧廊,那么就會(huì)銷毀监徘,當(dāng)即將醒來(lái)的時(shí)候,重新創(chuàng)建

一個(gè)RunLoop對(duì)應(yīng)一個(gè)線程
建議每一次啟動(dòng)RunLoop的時(shí)候吧碾,包裝一個(gè)自動(dòng)釋放池凰盔,臨時(shí)創(chuàng)建了很多對(duì)象,等著我們釋放倦春,在很多優(yōu)秀的開(kāi)源庫(kù)中户敬,都有這個(gè)說(shuō)明

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //延遲圖片加載
    
    _thread = [[WXThread alloc] initWithTarget:self
                                      selector:@selector(execute)
                                        object:nil];
    [_thread start];
}

- (void)execute{
//    該方法默認(rèn)不加入RunLoop中,使用schedule可以
    @autoreleasepool {
        NSTimer *timer = [NSTimer timerWithTimeInterval:0.3
                                                 target:self
                                               selector:@selector(test2)
                                               userInfo:nil
                                                repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末睁本,一起剝皮案震驚了整個(gè)濱河市尿庐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呢堰,老刑警劉巖抄瑟,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異枉疼,居然都是意外死亡皮假,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門骂维,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惹资,“玉大人,你說(shuō)我怎么就攤上這事席舍〔冀危” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵来颤,是天一觀的道長(zhǎng)汰扭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)福铅,這世上最難降的妖魔是什么萝毛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮滑黔,結(jié)果婚禮上笆包,老公的妹妹穿的比我還像新娘。我一直安慰自己略荡,他們只是感情好庵佣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著汛兜,像睡著了一般巴粪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天肛根,我揣著相機(jī)與錄音辫塌,去河邊找鬼。 笑死派哲,一個(gè)胖子當(dāng)著我的面吹牛臼氨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芭届,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼储矩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了褂乍?” 一聲冷哼從身側(cè)響起椰苟,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎树叽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體谦絮,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡题诵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了层皱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片性锭。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖叫胖,靈堂內(nèi)的尸體忽然破棺而出草冈,到底是詐尸還是另有隱情,我是刑警寧澤瓮增,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布怎棱,位于F島的核電站,受9級(jí)特大地震影響绷跑,放射性物質(zhì)發(fā)生泄漏拳恋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一砸捏、第九天 我趴在偏房一處隱蔽的房頂上張望谬运。 院中可真熱鬧,春花似錦垦藏、人聲如沸梆暖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)轰驳。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滑废,已是汗流浹背蝗肪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蠕趁,地道東北人薛闪。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像俺陋,于是被迫代替她去往敵國(guó)和親豁延。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • 一腊状、什么是runloop 字面意思是“消息循環(huán)诱咏、運(yùn)行循環(huán)”。它不是線程缴挖,但它和線程息息相關(guān)袋狞。一般來(lái)講,一個(gè)線程一次...
    WeiHing閱讀 8,146評(píng)論 11 111
  • ======================= 前言 RunLoop 是 iOS 和 OSX 開(kāi)發(fā)中非秤澄荩基礎(chǔ)的一個(gè)...
    i憬銘閱讀 883評(píng)論 0 4
  • 這是AF2.x經(jīng)典的代碼: 首先我們要明確一個(gè)概念,線程一般都是一次執(zhí)行完任務(wù)瘫析,就銷毀了砌梆。 而添加了runloop...
    有夢(mèng)想的老伯伯閱讀 2,001評(píng)論 5 13
  • 一. RunLoop簡(jiǎn)介 RunLoop字面意思是跑圈,在我們的項(xiàng)目中其實(shí)就是運(yùn)行循環(huán)贬循,而且是充滿靈性的死循環(huán)咸包,為...
    Fendouzhe閱讀 167評(píng)論 0 2
  • 萬(wàn)萬(wàn)沒(méi)想到今晚回家來(lái),婆婆為我煮了餛飩甘有。 今天晚上我又去健身房代課了诉儒,說(shuō)是代課,實(shí)際就是玩亏掀,也沒(méi)有工資忱反,因?yàn)槲覄倓?..
    島民小事事兒閱讀 234評(píng)論 0 1