進(jìn)程
1.進(jìn)程是指在系統(tǒng)中正在運(yùn)行
的一個(gè)應(yīng)用程序
2.每個(gè)進(jìn)程之間是相互獨(dú)立
的蒜撮,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空間中
線程
1.一個(gè)進(jìn)程要想執(zhí)行任務(wù),必須得有線程(每一個(gè)進(jìn)程至少要有一條線程)
2.一個(gè)進(jìn)程(程序)的所有任務(wù)都在線程中執(zhí)行
線程的串行
1.一個(gè)線程中任務(wù)的執(zhí)行是串行的
2.如果要在一個(gè)線程中執(zhí)行多個(gè)任務(wù),那么只能一個(gè)一個(gè)地按順序執(zhí)行這些任務(wù)
3.也就是說(shuō)萄焦,在同一時(shí)間內(nèi)驾诈,一個(gè)線程只能執(zhí)行一個(gè)任務(wù)
4.因此,也可以認(rèn)為線程是進(jìn)程中的一條執(zhí)行路徑
進(jìn)程和線程的比較
1.線程是CPU調(diào)用(執(zhí)行任務(wù))的最小單位
2.進(jìn)程是CPU分配資源和調(diào)度的單位
3.一個(gè)程序可以對(duì)應(yīng)多個(gè)進(jìn)程哑蔫,一個(gè)進(jìn)程中可以有多個(gè)線程钉寝,但至少要有一個(gè)線程
4.同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程的資源
多線程
1.一個(gè)進(jìn)程中可以開啟多條線程弧呐,每個(gè)線程可以并發(fā)(同時(shí))執(zhí)行不同的任務(wù)
2.多線程可以提高任務(wù)的執(zhí)行效率
多線程的原理
1.同一時(shí)間,CPU只能處理一條線程嵌纲,只有一條線程在執(zhí)行(單核)
2.多線程并發(fā)(同時(shí))執(zhí)行俘枫,其實(shí)是CPU快速的在多條線程之間調(diào)度(切換)
3.如果CPU調(diào)度線程的時(shí)間足夠快,就造成了多線程并發(fā)執(zhí)行的假象
4.如果線程非常多逮走,會(huì)導(dǎo)致CPU在很多的線程之間調(diào)度鸠蚪,消耗大量的CPU資源,每條線程被調(diào)度執(zhí)行的頻次會(huì)降低(線程的執(zhí)行效率降低)
多線程的優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn):
1.能適當(dāng)提高程序的執(zhí)行效率
2.能適當(dāng)提高資源利用率(CPU师溅,內(nèi)存利用率) - 缺點(diǎn):
1.創(chuàng)建線程是有開銷的茅信,iOS下主要成本包括:內(nèi)核數(shù)據(jù)結(jié)構(gòu)(大約1kb),椖钩簦空間(子線程512kb蘸鲸,主線程1mb,也可以使用-setStackSize:設(shè)置起便,但必須是4k的倍數(shù)棚贾,而且最小是16k),創(chuàng)建線程大約需要90毫秒的創(chuàng)建時(shí)間
2.如果開啟大量的線程榆综,會(huì)降低程序的性能
3.線程越多妙痹,CPU在調(diào)度線程上的開銷就越大
4.程序設(shè)計(jì)更加復(fù)雜,比如線程之間的通信鼻疮,多線程的數(shù)據(jù)共享
多線程在iOS開發(fā)中的應(yīng)用
主線程:
一個(gè)iOS程序運(yùn)行后怯伊,默認(rèn)會(huì)開啟一條線程,稱為主線程或UI線程主線程的主要作用:
1.顯示/刷新UI界面
2.處理UI事件(比如點(diǎn)擊事件判沟,滾動(dòng)事件耿芹,拖拽事件等)主線程的使用注意:
1.不要將比較耗時(shí)的操作放到主線程中
2.耗時(shí)操作會(huì)卡住主線程,嚴(yán)重影響UI的流暢度挪哄,給用戶一種卡的壞體驗(yàn)耗時(shí)操作的執(zhí)行
將耗時(shí)操作放在子線程(后臺(tái)線程吧秕,非主線程)-
獲得主線程
NSThread *main=[NSThread mainThread];
-
獲得當(dāng)前線程
NSThread *current=[NSThread currentThread];
判斷是否是主線程
1.number==1?
2.類方法
BOOL isMain= [NSThread isMainThread];
3.對(duì)象方法
BOOL ifMain=[current isMainThread];
- iOS中多線程的實(shí)現(xiàn)方案
技術(shù)方案 | 簡(jiǎn)介 | 語(yǔ)言 | 線程生命周期 | 使用頻率 |
---|---|---|---|---|
pthread | 一套通用的多線程API; 適用于unix/linux/windows等系統(tǒng)迹炼; 跨平臺(tái)/可移植砸彬; 使用難度大 |
C | 程序員管理 | 幾乎不用 |
NSThread | 使用更加面向?qū)ο螅?br>簡(jiǎn)單易用,可直接操作線程對(duì)象 | OC | 程序員管理 | 偶爾使用 |
GCD | 旨在替代NSThread 等線程技術(shù)斯入; 充分利用設(shè)備的多核 |
C | 自動(dòng)管理 | 經(jīng)常使用 |
NSOperation | 基于GCD(底層是GCD)砂碉; 比GCD 多了一些更簡(jiǎn)單實(shí)用的功能; 使用更加面向?qū)ο?/td> | OC | 自動(dòng)管理 | 經(jīng)常使用 |
pthread的簡(jiǎn)單使用
1.#import <pthread.h>
2. //創(chuàng)建線程對(duì)象
pthread_t thread;
//創(chuàng)建線程
/*
第一個(gè)參數(shù):線程對(duì)象 傳遞地址
第二個(gè)參數(shù):線程的屬性 可設(shè)為null
第三個(gè)參數(shù):指向函數(shù)的指針
第四個(gè)參數(shù):函數(shù)需要接受的參數(shù)
*/
pthread_create(&thread, NULL, test, NULL);
void *test(void * param){
return NULL;
}
NSThread的基本使用
- 方法一
/*
第一個(gè)參數(shù):目標(biāo)對(duì)象
第二個(gè)參數(shù):方法選擇器 調(diào)用的方法
第三個(gè)參數(shù):前面調(diào)用方法需要傳遞的參數(shù) 可以為nil
*/
NSThread *subthread=[[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"123"];
//設(shè)置線程的名字
subthread.name=@"subthread";
//優(yōu)先級(jí) 0.0(最低)--0.5(默認(rèn))--1.0( 最高)
subthread.threadPriority=1;
//需要手動(dòng)啟動(dòng)線程
[subthread start];
-(void)run:(NSString *)param{
}
- 方法二
//分離子線程刻两,自動(dòng)啟動(dòng)線程
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"分離子線程"];
- 方法三
//開啟一條后臺(tái)線程
[self performSelectorInBackground:@selector(run:) withObject:@"開啟一條后臺(tái)線程"];
后兩種方法的優(yōu)缺點(diǎn)
1.優(yōu)點(diǎn):
簡(jiǎn)單快捷
2.缺點(diǎn):
沒(méi)有辦法拿到線程對(duì)象增蹭,無(wú)法設(shè)置優(yōu)先級(jí)或其他屬性NSThread的生命周期
當(dāng)線程中的任務(wù)執(zhí)行完畢后才被釋放控制線程的狀態(tài)
1.創(chuàng)建線程
init
新建, 此時(shí)在內(nèi)存中存在磅摹,但是不在可調(diào)度線程池中
2.啟動(dòng)線程
-(void)start滋迈;
進(jìn)入就緒狀態(tài)霎奢,進(jìn)入可調(diào)度線程池,當(dāng)CPU調(diào)度時(shí)饼灿,進(jìn)入運(yùn)行狀態(tài)椰憋,當(dāng)線程任務(wù)執(zhí)行完畢,自動(dòng)進(jìn)入死亡狀態(tài)
3.阻塞/暫停線程
+(void)sleepUntilDate:(NSDate *)date;
+(void)sleepForTimeInterval:(NSTimeInterval)ti;
進(jìn)入阻塞狀態(tài)赔退,推出可調(diào)度線程池,當(dāng)時(shí)間到時(shí)证舟,再次進(jìn)入就緒狀態(tài)硕旗,進(jìn)入可調(diào)度池
4.強(qiáng)制停止線程
+(void)exit;
進(jìn)入死亡狀態(tài)女责,一旦線程死亡了漆枚,就不能再次開啟任務(wù)線程安全
多線程的安全隱患
1.資源共享
一塊資源可能會(huì)被多個(gè)線程共享,也就是多個(gè)線程可能會(huì)訪問(wèn)同一塊資源
比如多個(gè)線程訪問(wèn)同一個(gè)對(duì)象抵知,同一個(gè)變量墙基,同一個(gè)文件
當(dāng)多個(gè)線程訪問(wèn)同一塊資源時(shí),很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問(wèn)題安全隱患解決--互斥鎖
互斥鎖使用格式
@synchronized(鎖對(duì)象刷喜,通常為self){
//需要鎖定的代碼
}
鎖:必須是全局唯一的一把鎖残制,
鎖定一份代碼只用一把鎖,用多把鎖是無(wú)效的
1.注意加鎖的位置
2.注意加鎖的前提條件,多線程共享同一塊資源
3.注意加鎖是需要付出代價(jià)的掖疮,需要耗費(fèi)性能
4.加鎖的結(jié)果:線程同步
線程同步:多條線程在同一條線上執(zhí)行(按順序的執(zhí)行任務(wù))
互斥鎖的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
能有效防止因多線程搶奪資源造成的數(shù)據(jù)安全問(wèn)題
缺點(diǎn):
需要消耗大量的CPU資源互斥鎖的使用前提:
多條線程搶奪同一塊資源原子和非原子屬性
oc在定義屬性時(shí)有nonatomic和atomic兩種選擇
atomic:原子屬性初茶,為setter方法加鎖(默認(rèn)就是atomic)
線程安全,但需要消耗大量的資源
nonatomic:非原子屬性浊闪,不會(huì)為setter方法加鎖
非線性安全恼布,適合內(nèi)存小的移動(dòng)設(shè)備iOS開發(fā)的建議
1.所有屬性都聲明為nonatomic
2.盡量避免多線程搶奪同一資源
3.盡量將加鎖,資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器端處理搁宾,減小移動(dòng)客戶端的壓力線程間通信
在一個(gè)進(jìn)程中折汞,線程往往不是孤立存在的,多個(gè)線程之間需要經(jīng)常進(jìn)行通信線程間通信的體現(xiàn)
1.一個(gè)線程傳遞數(shù)據(jù)給另外一個(gè)線程
2.在一個(gè)線程中執(zhí)行完特定任務(wù)后盖腿,轉(zhuǎn)到另一個(gè)線程繼續(xù)執(zhí)行任務(wù)
線程間通信常用方法
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
-(void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
GCD
純c語(yǔ)言爽待,提供了非常多強(qiáng)大的函數(shù)
gcd的優(yōu)勢(shì)
1.gcd是蘋果公司為多核的并行運(yùn)算提出的解決方案
2.gcd會(huì)自動(dòng)利用更多的cpu內(nèi)核(比如雙核,四核)
3.gcd會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程奸忽,調(diào)度任務(wù)堕伪,銷毀線程)
4.程序員只需要告訴gcd想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼任務(wù)和隊(duì)列
任務(wù):執(zhí)行什么操作
隊(duì)列:用來(lái)存放任務(wù)gcd的使用就兩個(gè)步驟
1.定制任務(wù)栗菜,確定想做的事情
2.將任務(wù)添加到隊(duì)列中欠雌,gcd會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出,放到對(duì)應(yīng)的線程中執(zhí)行任務(wù)的取出遵循隊(duì)列的FIFO原則:先進(jìn)先出
執(zhí)行任務(wù)
同步:只能在當(dāng)前線程中執(zhí)行任務(wù)疙筹,不具備開啟新線程的能力富俄,需要立刻執(zhí)行禁炒,執(zhí)行完畢再執(zhí)行下面的
dispatch_sync(dispatch_queue_t queue, ^(void)block);
異步:可以在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力霍比,即使沒(méi)有執(zhí)行完畢幕袱,后面的也可以執(zhí)行
dispatch_async(dispatch_queue_t _Nonnull queue, ^(void)block);
隊(duì)列
并發(fā)隊(duì)列:可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))
并發(fā)功能只有在異步函數(shù)下才有效
串行隊(duì)列:讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后,在執(zhí)行下一個(gè)任務(wù))同步和異步主要影響:能不能開啟新的線程
并發(fā)和串行主要影響:任務(wù)的執(zhí)行方式
gcd的基本使用
//1.創(chuàng)建隊(duì)列
/*
第一個(gè)參數(shù):c語(yǔ)言的字符串悠瞬,就是一個(gè)標(biāo)識(shí)符们豌,用來(lái)區(qū)分隊(duì)列,沒(méi)有實(shí)際意義
第二個(gè)參數(shù):隊(duì)列類型
DISPATCH_QUEUE_CONCURRENT 并行隊(duì)列
DISPATCH_QUEUE_SERIAL 串行隊(duì)列
*/
dispatch_queue_t queue= dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT);//方法一
/*
第一個(gè)參數(shù):隊(duì)列優(yōu)先級(jí)
第二個(gè)參數(shù):暫時(shí)無(wú)用浅妆,寫0即可
*/
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//方法二望迎,獲得全局并發(fā)隊(duì)列
//2.封裝任務(wù),添加任務(wù)到隊(duì)列中
/*
第一個(gè)參數(shù):隊(duì)列
第二個(gè)參數(shù):要執(zhí)行的任務(wù)
*/
dispatch_async(queue, ^{
});
? | 并發(fā)隊(duì)列 | 串行隊(duì)列 | 主隊(duì)列 |
---|---|---|---|
異步函數(shù) | 會(huì)開啟多條線程凌外,隊(duì)列中的任務(wù)是并發(fā)執(zhí)行 | 會(huì)開啟線程辩尊,開一條線程,隊(duì)列中的任務(wù)是串行執(zhí)行 | 不會(huì)開啟線程康辑,所有任務(wù)都在主線程中執(zhí)行摄欲,隊(duì)列中的任務(wù)是串行執(zhí)行 |
同步函數(shù) | 不會(huì)開啟線程,隊(duì)列中的任務(wù)是串行執(zhí)行 | 不會(huì)開啟線程疮薇,隊(duì)列中的任務(wù)是串行執(zhí)行 | 在主線程中會(huì)產(chǎn)生死鎖胸墙,在子線程中沒(méi)有影響 |
- 并發(fā)隊(duì)列
兩種創(chuàng)建方法:
1.自己創(chuàng)建
dispatch_queue_t queue= dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT);
2.獲得全局并發(fā)隊(duì)列
dispatch_queue_t queue1=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- 串行隊(duì)列
兩種創(chuàng)建方法
1.自己創(chuàng)建
dispatch_queue_t queue= dispatch_queue_create("123", DISPATCH_QUEUE_SERIAL);
2.獲得主隊(duì)列(和主線程相關(guān)的隊(duì)列)
dispatch_queue_t queue1=dispatch_get_main_queue();
主隊(duì)列是gcd自帶的一種特殊的串行隊(duì)列
放在主隊(duì)列中的任務(wù),都會(huì)放到主線程中執(zhí)行
主隊(duì)列特點(diǎn)
如果主隊(duì)列發(fā)現(xiàn)當(dāng)前主線程有任務(wù)在執(zhí)行按咒,那么主隊(duì)列會(huì)暫停調(diào)用隊(duì)列中的任務(wù)劳秋,直到主線程空閑位置gcd實(shí)現(xiàn)線程間通信
gcd同步/異步函數(shù)嵌套使用同步/異步函數(shù)gcd的常用函數(shù)
- 延遲執(zhí)行
/*
第一個(gè)參數(shù):DISPATCH_TIME_NOW 從現(xiàn)在開始計(jì)算時(shí)間
第二個(gè)參數(shù):延遲的時(shí)間 gcd時(shí)間單位:納秒
第三個(gè)參數(shù):隊(duì)列
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
- 一次性代碼,不能放在懶加載中胖齐,主要用在單例中
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
});
- gcd柵欄函數(shù)
3.1 作用:控制多線程中并發(fā)任務(wù)的執(zhí)行順序玻淑,比如放置在任務(wù)1,任務(wù)2之后呀伙,任務(wù)3之前补履,則結(jié)果是等任務(wù)1,2都執(zhí)行完畢后剿另,再執(zhí)行任務(wù)3
3.2 注意:柵欄函數(shù)不能使用全局并發(fā)隊(duì)列
/*
第一個(gè)參數(shù):隊(duì)列
第二個(gè)參數(shù):操作
*/
dispatch_barrier_async(queue, ^{
//操作
});
- gcd快速迭代(遍歷)
for循環(huán)是同步的箫锤,gcd是開子線程和主線程一起完成遍歷任務(wù),任務(wù)的執(zhí)行是并發(fā)的
/*
第一個(gè)參數(shù):遍歷的次數(shù)
第二個(gè)參數(shù):隊(duì)列(只能傳并發(fā)隊(duì)列雨女,串行隊(duì)列無(wú)效果谚攒,主隊(duì)列會(huì)死鎖)
第三個(gè)參數(shù):index 索引
*/
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"%zd",index);
});
- gcd隊(duì)列組
gcd隊(duì)列組的使用
dispatch_queue_t queue2=dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group=dispatch_group_create();
/*
作用:
第一個(gè):封裝任務(wù)
第二個(gè):把任務(wù)添加到隊(duì)列中
第三個(gè):會(huì)監(jiān)聽(tīng)任務(wù)的執(zhí)行情況,通知group
*/
dispatch_group_async(group, queue2, ^{
});
dispatch_group_async(group, queue2, ^{
});
dispatch_group_async(group, queue2, ^{
});
//攔截通知氛堕,當(dāng)隊(duì)列組中所有的任務(wù)都執(zhí)行完畢的時(shí)候進(jìn)入到下面的方法
//內(nèi)部本身是異步的
dispatch_group_notify(group, queue2, ^{
});
老式寫法
dispatch_queue_t queue3=dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group1=dispatch_group_create();
//在該方法后面的異步任務(wù)會(huì)被納入到隊(duì)列組的監(jiān)聽(tīng)范圍馏臭,進(jìn)入群組
//enter和leave必須配套出現(xiàn)
dispatch_group_enter(group1);
dispatch_sync(queue3, ^{
//離開群組
dispatch_group_leave(group1);
});
dispatch_group_enter(group1);
dispatch_sync(queue3, ^{
//離開群組
dispatch_group_leave(group1);
});
//等待 等價(jià)于dispatch_group_notify,本身是阻塞的,即我不執(zhí)行讼稚,下面的也不執(zhí)行
//DISPATCH_TIME_FOREVER 表示死等括儒,直到隊(duì)列組中所有的任務(wù)都執(zhí)行完畢之后才執(zhí)行绕沈,
dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
NSOperation
作用:
配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線程編程具體步驟:
1.先將需要執(zhí)行的操作封裝到一個(gè)NSOperation對(duì)象中
2.將NSOperation對(duì)象添加到NSOperationQueue中
3.系統(tǒng)會(huì)自動(dòng)將NSOperationQueue中的NSOperation取出來(lái)
4.將取出的NSOperation封裝的操作放到一條新線程中執(zhí)行NSOperation的子類
NSOperation是個(gè)抽象類,并不具備封裝操作的能力帮寻,必須使用他的子類使用NSOperation子類的方式有3中
1.NSInvocationOperation
//1.創(chuàng)建操作乍狐,封裝任務(wù)
/*
第一個(gè)參數(shù):目標(biāo)對(duì)象
第二個(gè):調(diào)用的方法
第三個(gè):調(diào)用的方法的參數(shù)
*/
NSInvocationOperation *op1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];
2.NSBlockOperation
//1.創(chuàng)建操作,封裝任務(wù)
NSBlockOperation *op2=[NSBlockOperation blockOperationWithBlock:^{
//任務(wù)
}];
//追加任務(wù)
//注意:如果一個(gè)操作中的任務(wù)數(shù)量大于1固逗,那么會(huì)開子線程并發(fā)執(zhí)行任務(wù)
//注意:不一定是子線程浅蚪,有可能是主線程
[op2 addExecutionBlock:^{
//任務(wù)
}];
3.自定義子類繼承NSOperation,實(shí)現(xiàn)內(nèi)部的main方法
//告知要執(zhí)行的任務(wù)是什么
//有利于代碼隱蔽烫罩,有益于代碼復(fù)用
-(void)main{
//任務(wù)
}
創(chuàng)建好操作后
//2.啟動(dòng)/執(zhí)行操作
//注意:如果直接start掘鄙,那么不會(huì)創(chuàng)建新線程,就和一般的[self 方法名];效果一樣嗡髓,無(wú)法實(shí)現(xiàn)多線程編程
[op1 start];
[op2 start];
//2.創(chuàng)建隊(duì)列,這樣才可能實(shí)現(xiàn)多線程編程
/*
主隊(duì)列:[NSOperationQueue mainQueue]和gcd中的主隊(duì)列一樣收津,是串行隊(duì)列饿这,在主線程中執(zhí)行
非主隊(duì)列:[[NSOperationQueue alloc]init]非常特殊,因?yàn)橥瑫r(shí)具備并發(fā)和串行的功能
默認(rèn)情況下撞秋,非主隊(duì)列是一個(gè)并發(fā)隊(duì)列
*/
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
//3. 添加操作到隊(duì)列中,內(nèi)部已經(jīng)調(diào)用了start方法
[queue addOperation:op2];
//簡(jiǎn)便方法 首先創(chuàng)建了NSBlockOperation操作长捧,然后把操作添加到隊(duì)列里
[queue addOperationWithBlock:^{
}];
NSOperation的其他用法
NSOperationQueue *queue1=[[NSOperationQueue alloc]init];
//設(shè)置最大并發(fā)數(shù):同一時(shí)間最多有多少個(gè)操作/任務(wù)可以執(zhí)行
//設(shè)置為1則為串行隊(duì)列,但是不等于只開一條線程
//不能設(shè)置為0吻贿,因?yàn)闀?huì)不執(zhí)行任務(wù)
//大于1就是并發(fā)隊(duì)列
//設(shè)置為-1則代表最大值串结,不受限制
queue.maxConcurrentOperationCount=5;
//暫停 可以恢復(fù) 不能暫停當(dāng)前正在執(zhí)行的任務(wù),需要等當(dāng)前任務(wù)執(zhí)行完畢再暫停
//隊(duì)列中的任務(wù)也是有狀態(tài)的 已經(jīng)執(zhí)行完畢/正在執(zhí)行/排隊(duì)等待執(zhí)行
[queue setSuspended:YES];
//繼續(xù)
[queue setSuspended:NO];
//取消 不可以恢復(fù) 不能暫停當(dāng)前正在執(zhí)行的任務(wù)舅列,需要等當(dāng)前任務(wù)執(zhí)行完畢再暫停
//該方法內(nèi)部調(diào)用了所有操作的cancel方法
//自定義NSOperation
gh *op3=[[gh alloc]init];
//需要先在自定義的gh中的main方法中設(shè)置
if (op3.isCancelled==YES) {
return;
}
[queue cancelAllOperations];
NSOperation操作依賴和監(jiān)聽(tīng)
//添加操作依賴
//注意:不能循環(huán)依賴肌割,不會(huì)崩潰,但是誰(shuí)都不會(huì)執(zhí)行 可以跨隊(duì)列依賴
[op1 addDependency:op2];
[op2 addDependency:op3];
//操作監(jiān)聽(tīng)
op3.completionBlock = ^{
//操作
};
NSOperation實(shí)現(xiàn)線程間通信
NSOperationQueue *queue3=[[NSOperationQueue alloc]init];
NSBlockOperation *down=[NSBlockOperation blockOperationWithBlock:^{
//操作
//在主線程中更新UI
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
//在主線程操作UI更新
}];
}];
[queue3 addOperation:down];
以上差不多就是iOS中多線程的知識(shí)點(diǎn)了 帐要,如果哪里有錯(cuò)誤把敞,還希望告知一下