<p id="qitwt"></p>
      1. <object id="qitwt"><strong id="qitwt"></strong></object>
        <p id="qitwt"></p>
        <li id="qitwt"></li>
        <p id="qitwt"><del id="qitwt"><xmp id="qitwt"></xmp></del></p>
        <p id="qitwt"><label id="qitwt"></label></p>
      2. <acronym id="qitwt"></acronym>
        <p id="qitwt"></p>
        免費開源的iOS開發學習平臺

        線程(Thread)基礎知識

        現代的操作系統,包括iOS,都支持線程Thread的概念,每個進程可以包含多個線程,借助多個CPU的內核,可以同時處理多個任務。即便是在早期單核CPU的時代,操作系統也可以把CPU資源在多個線程之間進行切換,給用戶的感覺是多個任務在“同時”處理。

        進程與線程

        每個應用程序都有一個進程,例如在Mac系統中,可以通過活動監視器來查看當前Mac電腦正在運行的進程。每個進程可以包含多個線程,這些線程可以同時運行,并各自處理一些任務。早期的CPU只有一個核心,因此會交替處理各個線程中的任務,讓用戶產生一種多任務同時處理的“感覺”。當CPU擁有多個內核時,各個線程就可以分配到不同的CPU內核中進行處理,即為真正意義上的多任務同時處理。

        對于任意一個iOS應用,程序運行起來后,默認會產生一個主線程(MainThread),主線程專門用來處理UIKit對象的操作,如界面的顯示與更新、處理用戶交互事件等等。(請牢牢記憶這點,所有與UI相關的操作都要在主線程中進行)

        對于一個App應用來說,之所以需要引入多個線程,很大程度上是由于存在一些操作是非常耗時的,例如:發送網絡請求并等待服務器的響應,這種耗時操作是不能夠放在主線程中進行操作的,因為在等待的時間內,主線程被使用,用戶是不能做任何交互動作的,因而會極大影響用戶體驗。對于耗時的操作,需要再另外創建一個線程,放到后臺處理,當處理完成得到結果后,再返回主線程去設置UI界面,這就涉及到線程間通信的相關知識。

        多線程同時處理任務,還會涉及到線程安全(thread-safe)的問題,當多個線程對一個對象進行同時操作時,就會影響結果的正確性。因此,線程對某個對象操作時,需要使用到“鎖”的機制,即當一個線程操作一個對象的過程中,會給這個對象上鎖,其他線程就不能夠訪問該對象了。加鎖雖然解決了線程安全的問題,但帶來的另外一個弊端就是影響了程序運行的效率。

        當我們給一個自定義類中添加屬性的時候,屬性關鍵字其中就有:atomic和nonatomic的區分,其中:atomic是線程安全的,當有線程訪問這個屬性時,會為該屬性的setter方法加鎖,atomic是默認值。但是,我們在實際的開發中,都會把給屬性設置nonatomic關鍵字,因為對于移動設備來說,效率更加重要,但也需要程序員注意線程安全問題。

        NSThread類

        NSThred類是蘋果提供的管理線程的類,提供了一些線程管理的方法。但是隨著GCD和NSOperation的推出,NSThread的使用場景已經大大減少。在實際的開發中,偶爾會使用NSThread類來獲取一些線程信息。常用的一些方法如下:

        • 獲取當前線程對象
        + (NSThread *)currentThread; 
        
        • 獲取主線程對象
        + (NSThread *)mainThread;
        
        • 使主線程休眠ti秒
        + (void)sleepForTimeInterval:(NSTimeInterval)ti; 
        

        示例代碼

        下方的示例代碼中,點擊【顯示內容】按鈕,會對3個Label上顯示的文字進行設置,每個label上顯示的文字,都是從一個方法中獲取。但在獲取文字的方法實現中,都會對主線程進行阻塞3秒,在阻塞的過程中,用戶是無法進行任何操作的,除了點擊Home鍵退出應用。

        • 實現獲取字符串的方法,在每個方法中都會阻塞主線程3秒;
        -(NSString *) generateString1{
            //阻塞主進程
            [NSThread sleepForTimeInterval:3.0];
            NSString *string = @"hello world!";
            return string;
        }
        -(NSString *) generateString2{
            //阻塞主進程
            [NSThread sleepForTimeInterval:3.0];
            NSString *string = @"www.shengdelvshi.com!";
            return string;
        }
        -(NSString *) generateString3{
            //阻塞主進程
            [NSThread sleepForTimeInterval:3.0];
            NSString *string = @"2017!";
            return string;
        }
        
        • 實現【顯示內容】按鈕的點擊操作。
        - (IBAction)showContent:(id)sender {
            //記錄開始時間
            NSLog(@"\n Start Time:%@, \n Current Thread: %@, \n Main Thread: %@", [NSDate date], [NSThread currentThread], [NSThread mainThread]);
            self.label1.text = [self generateString1];
            self.label2.text = [self generateString2];
            self.label3.text = [self generateString3];
            //記錄結束時間
            NSLog(@"\n End Time:%@, \n Current Thread: %@, \n Main Thread: %@", [NSDate date], [NSThread currentThread], [NSThread mainThread]);
         }
        

        運行結果如下。我們可以看到程序執行的時間總共約有9秒鐘,并且都是在主線程中執行(線程ID = 1),在運行期間,按鈕是不能夠被點擊的。

        示例代碼

        https://github.com/99ios/11.1


        青青草国产成人久久_jizzjizz日本护士高清_亚洲 另类 国产 另类_99久久免费精品色老
        <p id="qitwt"></p>
          1. <object id="qitwt"><strong id="qitwt"></strong></object>
            <p id="qitwt"></p>
            <li id="qitwt"></li>
            <p id="qitwt"><del id="qitwt"><xmp id="qitwt"></xmp></del></p>
            <p id="qitwt"><label id="qitwt"></label></p>
          2. <acronym id="qitwt"></acronym>
            <p id="qitwt"></p>