iOS進程和線程

1. 什么是程序呜达、進程谣蠢、線程

1.1 程序:

由源代碼生成的可執(zhí)行應(yīng)用。(例如:QQ.APP)

1.2 進程:

一個正在運行的程序可以看做一個進程查近。(例如:正在運行的QQ就是一個進程)眉踱,進程擁有獨立運行所需的全部資源。

1.3 線程:

程序中獨立運行的代碼段霜威。(例如:接收QQ消息的代碼)
一個進程是由一或多個線程組成谈喳。進程只負責(zé)資源的調(diào)度和分配,線程才是程序真正的執(zhí)行單元戈泼,負責(zé)代碼的執(zhí)行婿禽。

2. 單線程與多線程有什么區(qū)別

2.1單線程

每個正在運行的程序(即進程),至少包含一個線程大猛,這個線程叫主線程扭倾。
主線程在程序啟動時被創(chuàng)建,用于執(zhí)行main函數(shù)胎署。
只有一個主線程的程序吆录,稱作單線程程序。
主線程負責(zé)執(zhí)行程序的所有代碼(UI展現(xiàn)以及刷新琼牧,網(wǎng)絡(luò)請求恢筝,本地存儲等等)。這些代碼只能順序執(zhí)行巨坊,無法并發(fā)執(zhí)行撬槽。

2.2多線程

擁有多個線程的程序,稱作多線程程序趾撵。
iOS允許用戶自己開辟新的線程侄柔,相對于主線程來講,這些線程占调,稱作子線程暂题。
可以根據(jù)需要開辟若干子線程
子線程和主線程是 都是 獨立的運行單元,各自的執(zhí)行互不影響究珊,因此能夠并發(fā)執(zhí)行薪者。

2.3區(qū)別

單線程程序:只有一個線程,代碼順序執(zhí)行剿涮,容易出現(xiàn)代碼阻塞(頁面假死)言津。
多線程程序:有多個線程攻人,線程間獨立運行,能有效的避免代碼阻塞悬槽,并且提高程序的運行性能怀吻。
注意:iOS中關(guān)于UI的添加和刷新必須在主線程中操作。

3. iOS多線程實現(xiàn)種類

主要由四種:NSThread初婆、NSoperationQueue蓬坡、NSobject、GCD

1.1輕量級別的多線程技術(shù)烟逊,

需要我們手動管理線程渣窜,還有提供的方法比較少,例如:串行宪躯,并發(fā)執(zhí)行這些實現(xiàn)起來相當(dāng)困難乔宿,開辟子線程的方法有兩種,這個需要我盟手動開啟線程访雪,也就是start方法详瑞,并且有返回值,返回值就是NSThread對象臣缀,可以設(shè)置線程名稱坝橡,設(shè)置線程的權(quán)限的等級一些操作參數(shù)。另一個是便利構(gòu)造器的方法開辟子線程精置,無返回值计寇,會自動啟動線程,不需要手動調(diào)用start方法脂倦。
#pragma mark -- NSThread 開辟子線程
// NSThread是我們自己手動開辟的子線程番宁,如果使用的是初始化方式就需要我們自己是釋放,如果使用的是便利構(gòu)造器方式它就會自動啟動赖阻,只要是我們手動開辟的線程蝶押,都需要我夢自己管理該線程,不只是啟動火欧,還有該線程使用完畢后的資源回收棋电,所以在NSThread的回調(diào)方法中需要加入自動釋放池來回收資源
- (void)threadInfo{
    // object:這個是回調(diào)方法的參數(shù);
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testThread:) object:@"我是參數(shù)"];
    // 當(dāng)使用初始化方法出來的主線程需要start啟動
    [thread start];
    //    NSLog(@"我是逗比");
    // 可以為開辟的子線程起名字
    thread.name = @"我是第二條線程";
    // 調(diào)整Thread的權(quán)限 線程權(quán)限的范圍值為0 ~ 1 苇侵。越大權(quán)限越高赶盔,先執(zhí)行的概率就會越高,由于是概率榆浓,所以并不能很準(zhǔn)確的的實現(xiàn)我們想要的執(zhí)行順序于未,默認(rèn)值是0.5
    thread.threadPriority = 1;
    // 取消當(dāng)前已經(jīng)啟動的線程
//    [thread cancel];
    // 通過遍歷構(gòu)造器開辟子線程
 //   [NSThread detachNewThreadSelector:@selector(testThread:) toTarget:self withObject:@"便利構(gòu)造器方式"];
    
}
1.2回調(diào)方法
如果子線程是我們手動開辟的,那么就需要我們來管理它運行所造成的資源回收
- (void)testThread:(NSString *)testString{
    // 如果子線程是我們手動開辟的,那么就需要我們來管理它運行所造成的資源回收
    @autoreleasepool {
        NSLog(@"參數(shù)----%@",testString);
        NSLog(@"testThread -- %@",[NSThread currentThread]);
        double sum = 0;
        for (int i = 1; i < 635500000; i ++) {
            sum += i;
        }
        NSLog(@"sum = %f---- %@",sum,[NSThread currentThread]);
        // 回到主線程 所有的NSObject對象或者NSobject的子類都有該方法沉眶,他是NSthread的另一種體現(xiàn)方式
        // waitUntilDone:是否將該回調(diào)方法執(zhí)行完在執(zhí)行后面的代碼,如果為YES:就必須等回調(diào)方法執(zhí)行完成之后才能執(zhí)行后面的代碼杉适,說白了就是阻塞當(dāng)前的線程谎倔,如果是NO:就是不等回調(diào)方法結(jié)束。不會阻塞當(dāng)前線程

      // 回到主線程
        [self performSelectorOnMainThread:@selector(backMainThread) withObject:nil waitUntilDone:YES];
    }
}
- (void)backMainThread{
      NSLog(@"回到主線程");
}

2.NSObject

只要是NSObject的子類或者對象都可以通過調(diào)用方法進入子線程和主線程猿推,其實這些方法所開辟的子線程也是NSThread的另一種體現(xiàn)方式片习。
開辟子線程:

[self performSelectorInBackground:@selector(aaa) withObject:nil];

進入主線程:

[self performSelectorOnMainThread:@selector(bbb) withObject:nil 
waitUntilDone:YES];

3.3.NSOperationQueue:他是將一組事件添加到隊列中,如果想讓這組事件是在主線程中執(zhí)行蹬叭,那么就需要主隊列[NSOperationQueue mainQueue];如果想將一組事件在子線程中執(zhí)行那么就需要其他隊列[[NSOperationQueue alloc] init];NSOperationQueue就是事件藕咏,它本身是一個抽象類,如果需要實現(xiàn)具體操作秽五,需要他的兩個子類
NSInvocationOperation和NSBlockOperation;事件本身與線程無關(guān)孽查,知識看你將他加到那種隊列中。如果加到隊列中想要是的時間順序執(zhí)行坦喘,需要給事件添加依賴關(guān)系盲再,添加依賴關(guān)系的時候兩個事件不能互為依賴。也可以設(shè)置時間的優(yōu)先級來提高它先執(zhí)行的概率瓣铣,但是不準(zhǔn)確答朋,還可以設(shè)置隊列最大并發(fā)行數(shù),來是事件順序執(zhí)行棠笑。

- (void)invocationOperationInfo{
    
    //  NSInvocationOperation 這個類只執(zhí)行一個操作梦碗,本身與線程無關(guān),意思就是蓖救,你把該類對象放到哪個線程里面洪规,他就在那個線程中執(zhí)行
    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(  invocationOperationAction) object:nil];
    // 改事件需手動執(zhí)行
    //    [invocationOperation start];
    // 通過Block方式增加一個事件
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"block --- %@",[NSThread currentThread]);
        
    }];
    // block方式的operation可以增加一組額外的block事件,通過這種方式的blockOperation添加的block事件順序無法掌握沒所以線程無法掌控
    for (int i = 0; i < 5; i ++) {
        [blockOperation addExecutionBlock:^{
            NSLog(@"execuBlock %@",[NSThread currentThread]);
            
        }];
    }
    // 當(dāng)所有的block事件都執(zhí)行完了,我們就可以讓他發(fā)出通知藻糖,告訴我們所有的事件都執(zhí)行完了
    blockOperation.completionBlock = ^{
        NSLog(@"不管上面的小弟怎么鬧淹冰,我是最后一個");
        NSLog(@"_____%@",[NSThread currentThread]);
        
    };
  
    // 主隊列  是將一組事件在主線程中執(zhí)行,不用設(shè)置任何屬性巨柒,一組事件都會順序執(zhí)行
    // 我們需要按照順序來執(zhí)行一組事件樱拴,轉(zhuǎn)讓個時候該怎么辦? 有兩種方式
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    // 第一種:設(shè)置隊列最大并發(fā)執(zhí)行事件的?個數(shù)洋满,該屬性默認(rèn)值是-1晶乔;意思是:該隊列中有多少個事件,就并發(fā)執(zhí)行多少個牺勾,如果設(shè)置并發(fā)事件設(shè)置為1正罢,那就是一次只執(zhí)行一個事件,
    //        queue.maxConcurrentOperationCount = 1;
    // 第二種:通過添加事件依賴驻民,事件依賴的意思就是說:當(dāng)?shù)匾粋€事件執(zhí)行完畢之后才執(zhí)行另一個事件翻具,在這里就是先執(zhí)行invocationOperation履怯,在執(zhí)行blockOperation,
    [blockOperation addDependency:invocationOperation];
    // 給隊列中增加事件
    [queue addOperation:invocationOperation];
    [queue addOperation:blockOperation];
}

4.GCD:

GCD效率比operationQueue要高一些裆泳,功能更強一些叹洲,目前有替代其他多線程的趨勢,他處理時間主要通過隊列來執(zhí)行工禾,分為兩種隊列运提,一種是串行,另一中是并行闻葵,系統(tǒng)提供給我們的是全局隊列民泵,一種是主隊列,添加時間函數(shù)為dispatch_async()槽畔;一般我們都用一部添加事件栈妆,最重要的原因是他不會阻塞當(dāng)前線程,全局隊列中所添加的異步事件坑定都是子線程中的厢钧,主隊列中添加事件不管同步還是異步都在主函數(shù)中運行签钩;!;悼臁铅檩!
一定記住會主線程要刷新UI原因是:1.iOS中為了效率更高,多數(shù)線程是沒有安全保證的莽鸿,在子線程中刷新UI有可能會遇到不可預(yù)知的錯誤昧旨,2.在子線程中刷新UI,只有當(dāng)前線程執(zhí)行完成祥得,才會刷新UI兔沃,和可能造成UI刷新不及時,影響用戶體驗级及,而且一般只有主線程才有UI刷新功能

創(chuàng)建一個串行隊列

- (void)serialQueuueCuanXing{
    
    // 創(chuàng)建一個串行隊列
    // dispatch_queue_create 函數(shù)是用來創(chuàng)建隊列使用乒疏,第一個參數(shù)為該隊列的標(biāo)簽,第二個參數(shù)為該隊列類型
    dispatch_queue_t serialQueue = dispatch_queue_create("串行", DISPATCH_QUEUE_SERIAL);
    // 給該隊列添加事件
    // 第一個參數(shù)為該事件所在的隊列饮焦,第二個參數(shù)為Block怕吴,該事件索要做的處理
    dispatch_sync(serialQueue, ^{
        NSLog(@"叼毛獸出生了---%@",[NSThread currentThread]);
    });
    dispatch_sync(serialQueue, ^{
        NSLog(@"叼毛獸會穿衣服了---%@",[NSThread currentThread]);
    });
    dispatch_sync(serialQueue, ^{
        NSLog(@"叼毛獸掛墻上了----%@",[NSThread currentThread]);
    });
    
     NSLog(@"執(zhí)行完了-- %@",[NSThread currentThread]);
    
}

創(chuàng)建一個并行隊列

// 并行隊列
- (void)seriaQueueBingXing{
    dispatch_queue_t seriaQueue = dispatch_queue_create("并行", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(seriaQueue, ^{
        NSLog(@"我是第一---%@",[NSThread currentThread]);
    });

    dispatch_async(seriaQueue, ^{
        NSLog(@"我是第二---%@",[NSThread currentThread]);
    });
    // 此函數(shù)會阻塞當(dāng)前線程,對主線程無影響。
    dispatch_barrier_async(seriaQueue, ^{
        NSLog(@"我正在執(zhí)行---%@",[NSThread currentThread]);
    });
    dispatch_async(seriaQueue, ^{
        NSLog(@"我是第三---%@",[NSThread currentThread]);
    });
    dispatch_async(seriaQueue, ^{
        NSLog(@"我是第四---%@",[NSThread currentThread]);
    });
    


}

5.系統(tǒng)提供的全局隊列

- (void)globalQueue{
    // 上面都是我們自主創(chuàng)建的隊列县踢,一般使用中转绷,我們都不會自己創(chuàng)建,而是使用系統(tǒng)提供的隊列硼啤,系統(tǒng)提供的隊列有全局隊列议经,在此隊列中可以添加多個異步事件,并發(fā)執(zhí)行
    // 一般我們都是使用系統(tǒng)提供的們不用自己創(chuàng)建
    // 第一個參數(shù)為該全局隊列的優(yōu)先級
    // 第二個參數(shù)暫時沒用,是系統(tǒng)為后面擴展來使用的煞肾,在將來的某一天使用到咧织,直接賦0就可以了
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(globalQueue, ^{
        NSLog(@"正在網(wǎng)絡(luò)下載或者其他一些耗時操作");
        // 耗時操作完成之后回主線程更新UI,GCD回主線程方式
        // 要得到主隊列,和operationQueue中的mainQueue是一樣的概念
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_async(mainQueue, ^{
            // 在此處進行UI刷新
            NSLog(@"mainQueue -- %@",[NSThread currentThread]);
            
        });
        
    });
    
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末籍救,一起剝皮案震驚了整個濱河市拯爽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钧忽,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逼肯,死亡現(xiàn)場離奇詭異耸黑,居然都是意外死亡,警方通過查閱死者的電腦和手機篮幢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門大刊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人三椿,你說我怎么就攤上這事缺菌。” “怎么了搜锰?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵伴郁,是天一觀的道長。 經(jīng)常有香客問我蛋叼,道長焊傅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任狈涮,我火速辦了婚禮狐胎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歌馍。我一直安慰自己握巢,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布松却。 她就那樣靜靜地躺著暴浦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晓锻。 梳的紋絲不亂的頭發(fā)上肉渴,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音带射,去河邊找鬼同规。 笑死瞳购,一個胖子當(dāng)著我的面吹牛宫屠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼铝条,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涩笤?” 一聲冷哼從身側(cè)響起贸桶,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎儒拂,沒想到半個月后寸潦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡社痛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年见转,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒜哀。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡斩箫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出撵儿,到底是詐尸還是另有隱情乘客,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布淀歇,位于F島的核電站易核,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏浪默。R本人自食惡果不足惜耸成,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浴鸿。 院中可真熱鬧井氢,春花似錦、人聲如沸岳链。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掸哑。三九已至约急,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間苗分,已是汗流浹背厌蔽。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留摔癣,地道東北人奴饮。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓纬向,卻偏偏與公主長得像,于是被迫代替她去往敵國和親戴卜。 傳聞我的和親對象是個殘疾皇子逾条,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

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

  • Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼投剥,方法是什么师脂?如果想延時執(zhí)行代碼、方法又是什么江锨? 1...
    AlanGe閱讀 1,736評論 0 17
  • 從哪說起呢吃警? 單純講多線程編程真的不知道從哪下嘴。啄育。 不如我直接引用一個最簡單的問題酌心,以這個作為切入點好了 在ma...
    Mr_Baymax閱讀 2,757評論 1 17
  • 多線程 在iOS開發(fā)中為提高程序的運行效率會將比較耗時的操作放在子線程中執(zhí)行,iOS系統(tǒng)進程默認(rèn)啟動一個主線程灸撰,用...
    郭豪豪閱讀 2,595評論 0 4
  • 線程浮毯、進程 1.iOS中的多線程操作、多線程方式泰鸡? 2.多線程的優(yōu)點和缺點分別是什么债蓝? 答:優(yōu)點:1、將耗時較長的...
    丶逐漸閱讀 1,376評論 0 8
  • 關(guān)中大地今天迎來初雪的洗禮盛龄,狂魔亂舞般的雪飄肆虐地趕走空氣里的塵埃饰迹,也像是為人類洗肺! 我是一個不能承受散場的人余舶,...
    修煉中的小妖閱讀 154評論 0 0