多線(xiàn)程

多線(xiàn)程:

基礎(chǔ)知識(shí):

進(jìn)程:在系統(tǒng)中正在運(yùn)行的應(yīng)用程序尿这。

每個(gè)進(jìn)程之間是獨(dú)立的朽缎,均運(yùn)行在其專(zhuān)用且受保護(hù)的內(nèi)存空間內(nèi)粮宛。進(jìn)程之間可以相互通信烹玉。

線(xiàn)程:每個(gè)進(jìn)程至少要有一個(gè)線(xiàn)程(線(xiàn)程是用來(lái)執(zhí)行任務(wù)的)。一個(gè)進(jìn)程中的所有任務(wù)都在線(xiàn)程中執(zhí)行钞馁。

線(xiàn)程的串行:一個(gè)線(xiàn)程中任務(wù)的執(zhí)行是串行的。如果想在一個(gè)線(xiàn)程中執(zhí)行多個(gè)任務(wù)匿刮,只能一個(gè)一個(gè)按順序執(zhí)行這些任務(wù)僧凰。同一時(shí)間內(nèi),一個(gè)線(xiàn)程只能執(zhí)行一個(gè)任務(wù)熟丸。

多線(xiàn)程:一個(gè)進(jìn)程中可以開(kāi)啟多個(gè)線(xiàn)程训措,每條線(xiàn)程可以并行(同時(shí))執(zhí)行不同的任務(wù)

多線(xiàn)程原理:

同一時(shí)間CPU只能處理一條線(xiàn)程,只有一條線(xiàn)程在工作光羞。

多線(xiàn)程同時(shí)執(zhí)行绩鸣,其實(shí)是CPU快速的在多條線(xiàn)程之間調(diào)度。如果CPU調(diào)度線(xiàn)程的時(shí)間足夠快纱兑,就造成了多線(xiàn)程并發(fā)執(zhí)行的假象呀闻。

多線(xiàn)程優(yōu)缺點(diǎn)

優(yōu)點(diǎn):能適當(dāng)提高程序的執(zhí)行效率;能適當(dāng)提高資源的利用率

缺點(diǎn):創(chuàng)建線(xiàn)程是有開(kāi)銷(xiāo)的潜慎,ios下主要成本包括:內(nèi)核數(shù)據(jù)結(jié)構(gòu)捡多,棧空間铐炫,創(chuàng)建線(xiàn)程大約要90ms的創(chuàng)建時(shí)間垒手;如果開(kāi)啟大量的線(xiàn)程,會(huì)降低程序的性能倒信;線(xiàn)程越多科贬,CPU在調(diào)度線(xiàn)程上的開(kāi)銷(xiāo)就越大;程序設(shè)計(jì)更加復(fù)雜:比如線(xiàn)程之間的通信鳖悠、多線(xiàn)程的數(shù)據(jù)共享榜掌。

多線(xiàn)程在IOS開(kāi)發(fā)中的應(yīng)用:

主線(xiàn)程:一個(gè)IOS程序運(yùn)行后优妙,默認(rèn)會(huì)開(kāi)啟1條線(xiàn)程,稱(chēng)為“主線(xiàn)程”或“UI線(xiàn)程”唐责。

主線(xiàn)程作用:顯示/刷新UI界面鳞溉;處理UI事件(比如點(diǎn)擊事件、滾動(dòng)事件鼠哥、拖拽事件等)熟菲。

耗時(shí)操作放在子線(xiàn)程(后臺(tái)線(xiàn)程、非主線(xiàn)程)朴恳。

注意:不要把比較耗時(shí)的操作放在主線(xiàn)程中抄罕。

iOS中多線(xiàn)程的實(shí)現(xiàn)方案

1 pthread:同于的多線(xiàn)程,跨平臺(tái)于颖,基于c語(yǔ)言呆贿,線(xiàn)程的生命周期由程序員管理。使用難度大森渐,使用頻率幾乎不用做入。

2 NSThread:基于OC語(yǔ)言,生命周期偶爾需要程序員管理(管理創(chuàng)建)同衣,偶爾使用竟块。

3 GCD:基于C語(yǔ)言,旨在代替NSThread等線(xiàn)程技術(shù)耐齐,充分利用設(shè)備的多核浪秘,生命周期自動(dòng)管理。

4 NSOperation:基于OC語(yǔ)言埠况,基于GCD耸携,使用更加面向?qū)ο螅菺CD多了一些簡(jiǎn)單實(shí)用的功能辕翰。經(jīng)常使用夺衍。

NSThread :3種創(chuàng)建方式

1. 使用alloc init創(chuàng)建

NSThread*thread =? [[NSThreadalloc]initWithTarget:selfselector:@selector(run:)object:@"rose"];

2.創(chuàng)建線(xiàn)程后自動(dòng)啟動(dòng)線(xiàn)程

[NSThreaddetachNewThreadSelector:@selector(run:)toTarget:selfwithObject:@"jack"];

3.隱式創(chuàng)建并啟動(dòng)線(xiàn)程

[selfperformSelectorInBackground:@selector(run:)withObject:@"Lily"];

多線(xiàn)程的安全隱患:

資源共享:多個(gè)線(xiàn)程可能會(huì)同時(shí)訪(fǎng)問(wèn)一塊資源

安全隱患解決—互斥鎖

互斥鎖使用格式

@synchronized(鎖對(duì)象){需要鎖定的代碼}

注意:鎖定一份代碼只用1把鎖,用多把鎖是無(wú)效的

互斥鎖的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):能有效防止因多線(xiàn)程搶奪資源造成的數(shù)據(jù)安全問(wèn)題

缺點(diǎn):需要消耗大量的CPU資源

互斥鎖使用的前提:多線(xiàn)程搶奪同一塊資源

線(xiàn)程同步:多條線(xiàn)程在同一條線(xiàn)上執(zhí)行(按順序地執(zhí)行任務(wù))

互斥鎖:使用了線(xiàn)程同步技術(shù)

原子和非原子屬性

nonatomic:非原子屬性喜命,不會(huì)加鎖

atomic:原子屬性刷后,為setter方法加鎖(默認(rèn)就是atomic)

IOS開(kāi)發(fā)的建議:所有屬性都聲明為nonatomic;盡量避免多線(xiàn)程搶奪同一塊資源渊抄。盡量將加鎖尝胆、資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器。

線(xiàn)程間通信:

一個(gè)進(jìn)程中护桦,線(xiàn)程往往不是孤立存在的含衔,多個(gè)線(xiàn)程之間需要進(jìn)行通信。

線(xiàn)程間通信的體現(xiàn):

1個(gè)線(xiàn)程傳遞數(shù)據(jù)給另一個(gè)線(xiàn)程

在1個(gè)線(xiàn)程中執(zhí)行完特定任務(wù)后,轉(zhuǎn)到另1個(gè)線(xiàn)程繼續(xù)執(zhí)行任務(wù)贪染。

GCD(Grand Central Dispatch):偉大的中樞調(diào)度器缓呛。純C語(yǔ)言

GCD優(yōu)勢(shì):是蘋(píng)果公司為多核的并行運(yùn)算提出的解決方案;自動(dòng)利用更多的CPU內(nèi)核杭隙;會(huì)自動(dòng)管理線(xiàn)程的生命周期哟绊。

GCD的2個(gè)核心概念

任務(wù)

隊(duì)列

GCD使用步驟2個(gè):

定制任務(wù)

將任務(wù)添加到隊(duì)列中:GCD會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出,放到對(duì)應(yīng)的線(xiàn)程中執(zhí)行痰憎;任務(wù)的取出遵循先進(jìn)先出原則票髓。

執(zhí)行任務(wù):GCD中有2個(gè)用來(lái)執(zhí)行任務(wù)的常用函數(shù):

同步:dispatch_sync();

異步:dispatch_async();

同步:只能在當(dāng)前線(xiàn)程中執(zhí)行任務(wù),不具備開(kāi)啟新線(xiàn)程的能力

異步:可以在新的線(xiàn)程中執(zhí)行铣耘,具備開(kāi)啟新線(xiàn)程的能力

隊(duì)列的類(lèi)型

并發(fā)隊(duì)列(Concurrent Dispatch Queue):多個(gè)任務(wù)并發(fā)執(zhí)行(自動(dòng)開(kāi)啟好多個(gè)線(xiàn)程執(zhí)行任務(wù))洽沟,并發(fā)功能只有在異步的時(shí)候才有效。

串行隊(duì)列(Serial Dispatch Queue):任務(wù)一個(gè)接一個(gè)的執(zhí)行

同步和異步主要影響:是否開(kāi)啟新的線(xiàn)程

串行和并行主要影響:是任務(wù)的執(zhí)行方式

GCD中還有個(gè)用來(lái)執(zhí)行任務(wù)的函數(shù)

dispatch_barrier_async(dispatch_queue_t queue, ^(void)block);

在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行蜗细,而且它后面的任務(wù)等它執(zhí)行完成之后才會(huì)執(zhí)行裆操。

這個(gè)queue不能是全局的并發(fā)隊(duì)列

GCD中常用的其他函數(shù)

延遲執(zhí)行:iOS中常見(jiàn)的延時(shí)執(zhí)行

1 調(diào)用NSObject的方法:

[selfperformSelector:@selector(run)withObject:nilafterDelay:2.0];

2使用GCD函數(shù)

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,2.0),dispatch_get_main_queue(), ^{

NSLog(@"");

});

3使用Timer

[NSTimerscheduledTimerWithTimeInterval:2.0target:selfselector:@selector(run)userInfo:nilrepeats:YES];

一次性代碼:

staticdispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

//默認(rèn)是線(xiàn)程安全的

});

dispatch_once:防止資源重復(fù)加載,但懶加載中不能使用[因?yàn)樗钦麄€(gè)程序運(yùn)行過(guò)程中只執(zhí)行一次]

快速迭代遍歷函數(shù)

dispatch_queue_tqueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_apply(10, queue, ^(size_tindex) {

//執(zhí)行10次代碼炉媒,index順序不確定

});

隊(duì)列組(group)

要求:首先踪区,分別異步執(zhí)行兩個(gè)耗時(shí)操作;其次吊骤,等2個(gè)異步操作都執(zhí)行完畢后朽缴,再回到主線(xiàn)程執(zhí)行。 如果想要快速高效的完成上述要求水援,可以使用隊(duì)列。

dispatch_group_tgroup =dispatch_group_create();

dispatch_group_async(group,dispatch_get_global_queue(0,0), ^{

//執(zhí)行第一個(gè)耗時(shí)操作

});

dispatch_group_async(group,dispatch_get_global_queue(0,0), ^{

//執(zhí)行第二個(gè)耗時(shí)操作

});

dispatch_group_notify(group,dispatch_get_main_queue(), ^{

//等前面的異步操作都執(zhí)行完畢后茅郎,回到主線(xiàn)程

});

GCD單例模式

單例模式:保證程序在運(yùn)行中蜗元,一個(gè)類(lèi)只有一個(gè)實(shí)例,而且該實(shí)例易于外界訪(fǎng)問(wèn)系冗。節(jié)約系統(tǒng)資源奕扣。

使用場(chǎng)合:共享資源(這個(gè)資源只創(chuàng)建一次)

普通創(chuàng)建單例模式方法

調(diào)用alloc實(shí)際上會(huì)繼承父類(lèi)的+(instancetype)allocWithZone:(struct_NSZone*)zone[allocWithZone分配內(nèi)存]

NSOperation:在GCD的繼承上對(duì)OC的封裝

作用:配合使用NSOperation和NSOperationQueue 也能夠?qū)崿F(xiàn)多線(xiàn)程編程

步驟:1 將需要的任務(wù)封裝到一個(gè)NSOperation對(duì)象中

2 將NSOperation對(duì)象添加到NSOperationQueue中

3 系統(tǒng)自動(dòng)將NSOperationQueue中的NSOperation取出來(lái)

4? 將取出的NSOperation封裝的任務(wù)放在一條線(xiàn)程中執(zhí)行

NSOperation是個(gè)抽象類(lèi),不具備封裝操作的能力掌敬,必須使用它的子類(lèi)

使用NSOperation子類(lèi)的方式有3種

1 NSInvocationOperation

2 NSBlockOperation

3 自定義子類(lèi)繼承NSOperation惯豆,實(shí)現(xiàn)內(nèi)部相應(yīng)的方法

NSOperationQueue的作用[其任務(wù)是放在自定義類(lèi)的-(void) main{}函數(shù)中即可]

NSOperation可以調(diào)用start方法來(lái)執(zhí)行任務(wù),但默認(rèn)是同步執(zhí)行的

如果將NSOperation添加到NSOperationQueue中則默認(rèn)是異步執(zhí)行的奔害。

注意:/* GCD隊(duì)列類(lèi)型:串行隊(duì)列[主隊(duì)列/自己創(chuàng)建的]并行隊(duì)列[全局/自己創(chuàng)建的]? */

/* NSOperation的隊(duì)列類(lèi)型1主隊(duì)列:[NSOperationQueue mainQueue]楷兽,凡是添加到主隊(duì)了中的NSOperation對(duì)象,都會(huì)放到主線(xiàn)程中執(zhí)行华临。

2其他隊(duì)列(串行芯杀、并發(fā)):[[NSOperationQueue alloc]init],添加到這種隊(duì)列中的NSOperation對(duì)象都會(huì)自動(dòng)放到子線(xiàn)程中執(zhí)行。

*/

控制線(xiàn)程數(shù)量? :

/*創(chuàng)建隊(duì)列*/

NSOperationQueue*queue = [[NSOperationQueuealloc]init];

/*設(shè)置最大并發(fā)操作數(shù)*/

queue.maxConcurrentOperationCount=x;

//如果最大并發(fā)數(shù)是1揭厚,那么就是串行隊(duì)列

掛起隊(duì)列 [暫停執(zhí)行]:

queue.suspend = YES;[NO却特,恢復(fù)隊(duì)列,繼續(xù)執(zhí)行]

蘋(píng)果官方建議:在[queuecancelAllOperations]即取消隊(duì)列的情況下筛圆,如果自定義NSOperation;執(zhí)行完一段耗時(shí)操作時(shí)要去判斷任務(wù)是不是被取消 即self.isCancelled裂明。

NSOperation中設(shè)置依賴(lài)

/*設(shè)置依賴(lài)*/

[operation3addDependency:operation1];

[operation3addDependency:operation2];

operation3放在operation1和operation2執(zhí)行完后執(zhí)行

可以在不同的隊(duì)列中設(shè)置依賴(lài)

NSOperation中監(jiān)聽(tīng)

op5.completionBlock= ^{

NSLog(@"op5執(zhí)行完畢---%@",[NSThreadcurrentThread]);

};

NSOperation線(xiàn)程之間的通信

[[NSOperationQueuemainQueue]addOperationWithBlock:^{

//回到主線(xiàn)程中執(zhí)行

}];

在NSOpeation中合并圖片,[等待圖一和圖二下載好在合成]可以使用依賴(lài)

多圖片下載

可以使用第三方框架:SDWebImage

[cell.imageViewsd_setImageWithURL:[NSURLURLWithString:app.icon]placeholderImage:[UIImageimageNamed:@"aa"]];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末太援,一起剝皮案震驚了整個(gè)濱河市闽晦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌粉寞,老刑警劉巖尼荆,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異唧垦,居然都是意外死亡捅儒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)振亮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)巧还,“玉大人,你說(shuō)我怎么就攤上這事坊秸◆锏唬” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵褒搔,是天一觀(guān)的道長(zhǎng)阶牍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)星瘾,這世上最難降的妖魔是什么走孽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮琳状,結(jié)果婚禮上磕瓷,老公的妹妹穿的比我還像新娘。我一直安慰自己念逞,他們只是感情好困食,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著翎承,像睡著了一般硕盹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叨咖,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天莱睁,我揣著相機(jī)與錄音待讳,去河邊找鬼。 笑死仰剿,一個(gè)胖子當(dāng)著我的面吹牛创淡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播南吮,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼琳彩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了部凑?” 一聲冷哼從身側(cè)響起露乏,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涂邀,沒(méi)想到半個(gè)月后瘟仿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡比勉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年劳较,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浩聋。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡观蜗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衣洁,到底是詐尸還是另有隱情墓捻,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布坊夫,位于F島的核電站砖第,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏环凿。R本人自食惡果不足惜梧兼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拷邢。 院中可真熱鬧,春花似錦屎慢、人聲如沸瞭稼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)环肘。三九已至,卻和暖如春集灌,著一層夾襖步出監(jiān)牢的瞬間悔雹,已是汗流浹背复哆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腌零,地道東北人梯找。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像益涧,于是被迫代替她去往敵國(guó)和親锈锤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

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