RunLoop 三 : 使用RunLoop線程保活的封裝

RunLoop 二 : RunLoop在實際中的應用篇幅中我們介紹了runloop在項目中的具體用法,并且創(chuàng)建了一個可以控制生命周期的線程.今天我們就用OCC語言兩種方法封裝一個線程笨曷牛活的工具類:

一:使用OC語言封裝:

// 監(jiān)控線程生命周期
@interface MYThread : NSThread

@end


@implementation MYThread

- (void)dealloc{
    NSLog(@"%s",__func__);
}

@end


@interface HHSaveLifeThread ()

@property (nonatomic,strong)MYThread *thread;
///  控制runloop是否停止循環(huán)
@property (nonatomic,assign)BOOL isStop;

@end


@implementation HHSaveLifeThread


- (instancetype)init{
    if (self = [super init]) {
        //默認runloop不停止,一直循環(huán)
        self.isStop = NO;
        __weak typeof(self) weakSelf = self;
        self.thread = [[MYThread alloc]initWithBlock:^{
            //保住此線程的命,獲取當前線程的 runloop ,添加任務
            NSPort *port = [[NSPort alloc]init];
            [[NSRunLoop currentRunLoop]addPort:port forMode:NSDefaultRunLoopMode];
            while (weakSelf && !weakSelf.isStop) {
                [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
        }];
        [self.thread start];
    }
    return self;
}


// 執(zhí)行任務
- (void)executeTaskWithBlock:(void (^)(void))taskBlock{
    if(!self.thread || !taskBlock) return;
    [self performSelector:@selector(__executeTaskWithBlock:) onThread:self.thread withObject:taskBlock waitUntilDone:NO];
}

// 停止
- (void)stop{
    
    if (!self.thread) return;
    [self performSelector:@selector(__stopRunloop) onThread:self.thread withObject:nil waitUntilDone:YES];
}


- (void)dealloc{
    [self stop];
    NSLog(@"%s",__func__);
}

#pragma mark 私有api
/// 停止 runloop 循環(huán)
- (void)__stopRunloop{
    self.isStop = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.thread= nil;
}


- (void)__executeTaskWithBlock:(void (^)(void))taskBlock{
    taskBlock();
}

點擊這里下載OC版本demo.

二:使用C語言封裝:

// 監(jiān)控線程生命周期
@interface MYThread : NSThread

@end


@implementation MYThread

- (void)dealloc{
    NSLog(@"%s",__func__);
}

@end


@interface HHSaveLifeThread ()

@property (nonatomic,strong)MYThread *thread;
///  控制runloop是否停止循環(huán)
@property (nonatomic,assign)BOOL isStop;

@end


@implementation HHSaveLifeThread


- (instancetype)init{
    if (self = [super init]) {
        //默認runloop不停止,一直循環(huán)
        self.isStop = NO;
        __weak typeof(self) weakSelf = self;
        self.thread = [[MYThread alloc]initWithBlock:^{
            //保住此線程的命,獲取當前線程的 runloop ,添加任務
            NSLog(@"-------------start-------------");
            //創(chuàng)建一個上下文環(huán)境
            CFRunLoopSourceContext context = {0};
            //創(chuàng)建一個source源
            CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
            //runloop添加source源
            CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
            // 最后一個參數(shù)如果為 true : 循環(huán)一次后就退出 ,  為 false ,不退出
//            while (weakSelf && !weakSelf.isStop) {
                //啟動runloop
                CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1E30, false);
//            }
            NSLog(@"-------------end-------------");
        }];
        [self.thread start];
    }
    return self;
}


// 執(zhí)行任務
- (void)executeTaskWithBlock:(void (^)(void))taskBlock{
    if(!self.thread || !taskBlock) return;
    [self performSelector:@selector(__executeTaskWithBlock:) onThread:self.thread withObject:taskBlock waitUntilDone:NO];
}

// 停止
- (void)stop{
    
    if (!self.thread) return;
    [self performSelector:@selector(__stopRunloop) onThread:self.thread withObject:nil waitUntilDone:YES];
}


- (void)dealloc{
    [self stop];
    NSLog(@"%s",__func__);
}

#pragma mark 私有api
/// 停止 runloop 循環(huán)
- (void)__stopRunloop{
//    self.isStop = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.thread= nil;
}


- (void)__executeTaskWithBlock:(void (^)(void))taskBlock{
    taskBlock();
}

點擊這里下載C語言版本demo.

思考:

1. 封裝此工具為什么給 NSThread 添加分類這種方式不太好?

答:因為如果使用分類的話,給分類添加屬性比較麻煩,需要用到 associate 關聯(lián)對象這種技術.

2. 為什么不采用繼承自 NSThread 這種方式?

答:直接繼承自 NSThread 這種方式不太安全,因為 NSThread 類中暴露了很多直接操作 線程 的 API,比如 start,cancle,stop等,其他使用此工具的開發(fā)者可能會調動 NSThread 中的方法 打亂 此工具的生命周期.這樣的話我們也無法保證線程的聲明周期,所以我們繼承自 NSObject 更好一些.把線程操作相關的方法封裝起來,更安全.

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市适贸,隨后出現(xiàn)的幾起案子馆蠕,更是在濱河造成了極大的恐慌,老刑警劉巖是尔,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件殉了,死亡現(xiàn)場離奇詭異,居然都是意外死亡拟枚,警方通過查閱死者的電腦和手機薪铜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恩溅,“玉大人隔箍,你說我怎么就攤上這事〗畔纾” “怎么了蜒滩?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奶稠。 經(jīng)常有香客問我帮掉,道長,這世上最難降的妖魔是什么窒典? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任蟆炊,我火速辦了婚禮,結果婚禮上瀑志,老公的妹妹穿的比我還像新娘涩搓。我一直安慰自己,他們只是感情好劈猪,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布昧甘。 她就那樣靜靜地躺著,像睡著了一般战得。 火紅的嫁衣襯著肌膚如雪充边。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天常侦,我揣著相機與錄音浇冰,去河邊找鬼。 笑死聋亡,一個胖子當著我的面吹牛肘习,可吹牛的內容都是我干的。 我是一名探鬼主播坡倔,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼漂佩,長吁一口氣:“原來是場噩夢啊……” “哼脖含!你這毒婦竟也來了?” 一聲冷哼從身側響起投蝉,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤养葵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瘩缆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體关拒,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年咳榜,在試婚紗的時候發(fā)現(xiàn)自己被綠了夏醉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡涌韩,死狀恐怖畔柔,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情臣樱,我是刑警寧澤靶擦,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站雇毫,受9級特大地震影響玄捕,放射性物質發(fā)生泄漏。R本人自食惡果不足惜棚放,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一枚粘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧飘蚯,春花似錦馍迄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至峦甩,卻和暖如春赘来,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凯傲。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工犬辰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泣洞。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓忧风,卻偏偏與公主長得像,于是被迫代替她去往敵國和親球凰。 傳聞我的和親對象是個殘疾皇子狮腿,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,092評論 1 32
  • 1.設計模式是什么缘厢? 你知道哪些設計模式,并簡要敘述甩挫?設計模式是一種編碼經(jīng)驗贴硫,就是用比較成熟的邏輯去處理某一種類型...
    龍飝閱讀 2,140評論 0 12
  • 1.設計模式是什么? 你知道哪些設計模式伊者,并簡要敘述英遭? 設計模式是一種編碼經(jīng)驗,就是用比較成熟的邏輯去處理某一種類...
    司馬DE晴空閱讀 1,281評論 0 7
  • 其實亦渗,我最不喜歡就是聽到我媽勸說別人生二胎挖诸。 我是家里的老大,我父親是那種重男輕女思想很重的人法精,我媽也是非常傳統(tǒng)的...
    狂愛美甲木子先生閱讀 152評論 0 0
  • 看過《搏擊俱樂部》多律,里面有段話還是挺有意思的,記錄下來搂蜓。 “安全套是我們這一代人的水晶鞋狼荞,每遇到一個陌生人...
    Facingmyself閱讀 208評論 0 4