• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 298  文章 - 377  trackbacks - 0
            <2016年11月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            常用鏈接

            留言簿(34)

            隨筆分類

            隨筆檔案

            文章檔案

            相冊

            收藏夾

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            在開發(fā)的時候 因為沒有好好去了解三者的差異性 一時貪圖便捷 一味使用NSThread開啟異步線程 線程爆滿沒有及時關(guān)閉銷毀 挖了坑吃了虧。 
            今天就在這里簡單寫寫三個的用法和差異性:

            NSThread 封裝性最差,主要基于thread使用,方便使用,缺點是需要手動關(guān)閉; 
            GCD基于C的API,代碼看起來比較亂(高大上),主要基于task使用; 
            NSOperation是基于GCD,被封裝成NSObject對象使用,主要基于隊列使用。

            NSThread的使用

            NSThread 方法

            1.創(chuàng)建:

            //需要手動開啟 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; [thread start]; 
            • 1
            • 2
            • 3
            • 1
            • 2
            • 3
            //或 自動開啟線程     [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
            • 1
            • 2
            • 1
            • 2
            //或 隱式創(chuàng)建并開啟線程     [self performSelectorInBackground:@selector(run) withObject:nil];
            • 1
            • 2
            • 1
            • 2

            ②獲取主線程和判斷是否為主線程

             + (NSThread *)mainThread; // 獲得主線程     - (BOOL)isMainThread; // 是否為主線程     + (BOOL)isMainThread; // 是否為主線程
            • 1
            • 2
            • 3
            • 1
            • 2
            • 3

            ③或許當前線程和線程名稱

            NSThread *current = [NSThread currentThread];     - (void)setName:(NSString *)name;
            • 1
            • 2
            • 1
            • 2

            ④線程中的通信 線程A跳去線程B

            //選擇主線程     - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;     //選擇特定線程     - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait; 
            • 1
            • 2
            • 3
            • 4
            • 5
            • 1
            • 2
            • 3
            • 4
            • 5

            ⑤回到主線程更新UI

            [self performSelectorOnMainThread:@selector(appendTextView:) withObject:message waitUntilDone:YES];
            • 1
            • 1

            ⑥線程睡眠

            + (void)sleepUntilDate:(NSDate *)date;     + (void)sleepForTimeInterval:(NSTimeInterval)ti;
            • 1
            • 2
            • 1
            • 2

            ⑦NSThread 線程取消和線程銷毀 
            線程取消- (void)cancel; 
            實際上只是把isCancel狀態(tài)置為YES,沒有實際上銷毀線程。要實現(xiàn)取消的功能,我們需要自己在線程的main函數(shù)中定期檢查isCancelled狀態(tài)來判斷線程是否需要退出,當isCancelled為YES的時候,我們手動退出。如果我們沒有在main函數(shù)中檢查isCancelled狀態(tài),那么調(diào)用-cancel將沒有任何意義。 
            線程銷毀 - (void)exit; 
            個會立即終止線程,即使任務(wù)沒有完成。有可能導致內(nèi)存泄漏等。 
            注意:對于有runloop的線程,可以使用CFRunLoopStop()結(jié)束runloop配合-cancel結(jié)束線程 
            runloop啟動的方法中run和runUntilDate:都無法使用CFRunLoopStop()退出,只有runMode:beforeDate:可以響應(yīng)CFRunLoopStop(),所以要想使用CFRunLoopStop()退出runloop,必須使用runMode:beforeDate:啟動

            NSThread 完整例子

             - (void)viewDidLoad{      // ①創(chuàng)建線程  b并指定方法threadTest     self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadTest) object:nil];      //②在線程啟動之前設(shè)置線程優(yōu)先級       self.thread.qualityOfService = NSQualityOfServiceDefault;      //③啟動線程     [self.thread start];   } /*由于線程的創(chuàng)建和銷毀非常消耗性能,大多情況下,我們需要復(fù)用一個長期運行的線程來執(zhí)行任務(wù)。在線程啟動之后會首先執(zhí)行-threadStar,正常情況下threadStar方法執(zhí)行結(jié)束之后,線程就會退出。為了線程可以長期復(fù)用接收消息,我們需要在threadStar中給thread添加runloop*/ - (void)threadStar{          // ①給線程設(shè)置名字         [[NSThread currentThread] setName:@"myThread"];          // ②給線程添加runloop         NSRunLoop *runLoop = [NSRunLoop currentRunLoop];              //③給runloop添加數(shù)據(jù)源         [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];            //④:檢查isCancelled         while (![[NSThread currentThread] isCancelled]) {                    //⑤啟動runloop               [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];           } }  
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20
            • 21
            • 22
            • 23
            • 24
            • 25
            • 26
            • 27
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 10
            • 11
            • 12
            • 13
            • 14
            • 15
            • 16
            • 17
            • 18
            • 19
            • 20
            • 21
            • 22
            • 23
            • 24
            • 25
            • 26
            • 27

            ①:設(shè)置線程的名字,這一步不是必須的,主要是為了debug的時候更方便,可以直接看出這是哪個線程

            ②:自定義的線程默認是沒有runloop的,調(diào)用-currentRunLoop,方法內(nèi)部會為線程創(chuàng)建runloop

            ③:如果沒有數(shù)據(jù)源,runloop會在啟動之后會立刻退出。所以需要給runloop添加一個數(shù)據(jù)源,這里添加的是NSPort數(shù)據(jù)源

            ④:定期檢查isCancelled,當外部調(diào)用-cancel方法將isCancelled置為YES的時候,線程可以退出

            ⑤:啟動runloop

            在耗時操作中再次使用self.thread,這里把耗時操作loadImage扔給它去做:

            [self performSelector:@selector(loadImage) onThread:self.thread withObject:nil waitUntilDone:NO] 
            • 1
            • 2
            • 1
            • 2

            最后,當你想要結(jié)束這個線程的時候,使用CFRunLoopStop()配合-cancel來結(jié)束線程:

            //在self.thread內(nèi)部直接調(diào)用cancelThread方法 //在其他線程則用[self performSelector:@selector(cancelThread) onThread:self.thread withObject:nil waitUntilDone:NO]   - (void)cancelThread {     [[NSThread currentThread] cancel];     CFRunLoopStop(CFRunLoopGetCurrent()); }
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9

            GCD的使用

            1?⃣獲取一個全局隊列

            dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  /*     全局隊列的四種類型:     DISPATCH_QUEUE_PRIORITY_HIGH     DISPATCH_QUEUE_PRIORITY_DEFAULT     DISPATCH_QUEUE_PRIORITY_LOW     DISPATCH_QUEUE_PRIORITY_BACKGROUND //等待所有比它級別高的隊列中的任務(wù)執(zhí)行完或CPU空閑的時候才會執(zhí)行自己的任務(wù) */
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 8
            • 9

            ① 創(chuàng)建串行隊列/并發(fā)隊列

            //串行隊列    dispatch_queue_t serialQueue;    serialQueue = dispatch_queue_create("com.example.SerialQueue", NULL);    //并發(fā)隊列   dispatch_queue_t concurrentQueue;    concurrentQueue = dispatch_queue_create("com.example.ConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7
            • 1
            • 2
            • 3
            • 4
            • 5
            • 6
            • 7

            ②獲取主隊列

            dispatch_queue_t mainQueue; mainQueue = dispatch_get_main_queue();
            • 1
            • 2
            • 1
            • 2

            ③添加到任務(wù)隊列執(zhí)行操作

            //異步執(zhí)行 dispatch_queue_t myCustomQueue; myCustomQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL); dispatch_async(myCustomQueue, ^{     NSLog("Do some work here."); }); //同步執(zhí)行 dispatch_sync(myCustomQueue, ^{     NSLog("Do some more work here."); });
            posted on 2016-11-04 23:32 聶文龍 閱讀(313) 評論(0)  編輯 收藏 引用
            久久综合给合综合久久| 亚洲国产欧美国产综合久久| 久久亚洲精品国产亚洲老地址| 99久久精品国产高清一区二区 | 欧美午夜A∨大片久久| 亚洲精品国精品久久99热一| 国产香蕉久久精品综合网| 久久这里有精品视频| 久久久久女人精品毛片| 精品久久久久久无码不卡| 99久久免费只有精品国产| 一级做a爰片久久毛片人呢| 久久精品国产亚洲AV电影| 亚洲AV无码久久| 99久久成人国产精品免费| 久久国产精品久久| 久久久久国产视频电影| 热综合一本伊人久久精品| 四虎国产精品成人免费久久| 久久国产精品二国产精品| 久久精品国产精品亚洲毛片| 18岁日韩内射颜射午夜久久成人| 久久se精品一区二区影院 | 99精品国产免费久久久久久下载| 狠狠久久综合| 乱亲女H秽乱长久久久| 亚洲精品无码久久千人斩| 久久er99热精品一区二区| 伊人久久免费视频| 久久久久久精品久久久久| 久久久久一区二区三区| 久久伊人精品一区二区三区| 久久人妻AV中文字幕| 欧美精品久久久久久久自慰| 久久国产亚洲精品无码| 色欲综合久久中文字幕网| 久久国产美女免费观看精品| 午夜精品久久久久久99热| 亚洲国产天堂久久综合网站| 丁香色欲久久久久久综合网| 久久九九久精品国产|