iOS多線程

一、進(jìn)程與線程

1.進(jìn)程:

系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序,每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空間內(nèi)

2.線程:

1個(gè)進(jìn)程要想執(zhí)行任務(wù),必須得有線程(每一個(gè)進(jìn)程至少要有一條線程);線程是進(jìn)程的基本執(zhí)行單元,一個(gè)進(jìn)程(程序)的所有任務(wù)都在線程中執(zhí)行
1個(gè)線程中執(zhí)行任務(wù)是串行的,同一時(shí)間只能執(zhí)行一個(gè)任務(wù),順序執(zhí)行所有任務(wù);

4.多線程:

一個(gè)進(jìn)程可以開啟多條線程,每條線程可以并發(fā)(同時(shí))執(zhí)行不同的任務(wù);多線程可以提高程序的執(zhí)行效率

多線程原理:

同一時(shí)間,CPU只能處理1條線程,只有1條線程在工作(執(zhí)行);多線程并發(fā)(同時(shí))執(zhí)行,其實(shí)是CPU快速地在多條線程之間調(diào)度(切換)如果CPU調(diào)度線程的時(shí)間足夠快,就造成了多線程并發(fā)執(zhí)行的假象

5.主線程:

一個(gè)iOS程序運(yùn)行后,默認(rèn)會開啟1條線程,稱為“主線程”或“UI線程”

主線程的主要作用

<1>顯示\刷新UI界面
<2>處理UI事件(比如點(diǎn)擊事件、滾動事件、拖拽事件等)

主線程的使用注意

<1>別將比較耗時(shí)的操作放到主線程中
<2>耗時(shí)操作會卡住主線程,嚴(yán)重影響UI的流暢度,給用戶一種“卡”的壞體驗(yàn)

二、多線程技術(shù)

column column
計(jì)數(shù)方案 簡介 語言 線程生命周期 使用頻率
pthread 一套通用的多線程API,適用于Unix\Linux\Windows等系統(tǒng),跨平臺\可移植,使用難度大 C 程序員管理 幾乎不用
NSTread 使用更加面向?qū)ο?,簡單易用,可直接操作線程對象 OC 程序員管理 偶爾使用
GCD 旨在代替NSTread等多線程技術(shù),充分利用設(shè)備的多核 C 自動管理 經(jīng)常使用
NSOperation 基于GCD(底層是GCD),比GCD多了一些更簡單使用的功能,使用更加面向?qū)ο?/td> OC 自動管理 經(jīng)常使用

1.NSTread

一個(gè)NSThread對象就代表一條線程

<1>創(chuàng)建、啟動線程

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
// 線程一啟動,就會在線程thread中執(zhí)行self的run方法

<2>主線程相關(guān)用法

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

<3>獲得當(dāng)前線程
NSThread *current = [NSThread currentThread];

<4>線程的調(diào)度優(yōu)先級

+ (double)threadPriority;
+ (BOOL)setThreadPriority:(double)p;
- (double)threadPriority;
- (BOOL)setThreadPriority:(double)p;

調(diào)度優(yōu)先級的取值范圍是0.0 ~ 1.0,默認(rèn)0.5,值越大,優(yōu)先級越高

自己開發(fā)時(shí),建議一般不要修改優(yōu)先級

<5>線程的名字

- (void)setName:(NSString *)n;
- (NSString *)name;

<6>創(chuàng)建線程后自動啟動線程

[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

<7>隱式創(chuàng)建并啟動線程

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

<8>啟動線程

- (void)start; 

// 進(jìn)入就緒狀態(tài) -> 運(yùn)行狀態(tài)。當(dāng)線程任務(wù)執(zhí)行完畢,自動進(jìn)入死亡狀態(tài)

<9>阻塞(暫停)線程

+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 進(jìn)入阻塞狀態(tài)

<10>強(qiáng)制停止線程

+ (void)exit;
// 進(jìn)入死亡狀態(tài)

注意:一旦線程停止(死亡)了,就不能再次開啟任務(wù)

2.多線程的安全問題

<1>資源共享
1塊資源可能會被多個(gè)線程共享,也就是多個(gè)線程可能會訪問同一塊資源
比如多個(gè)線程訪問同一個(gè)對象、同一個(gè)變量、同一個(gè)文件

當(dāng)多個(gè)線程訪問同一塊資源時(shí),很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問題

<2>安全隱患解決
1.互斥鎖使用格式
@synchronized(鎖對象) { // 需要鎖定的代碼 }
注意:鎖定1份代碼只用1把鎖,用多把鎖是無效的

互斥鎖的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):能有效防止因多線程搶奪資源造成的數(shù)據(jù)安全問題
缺點(diǎn):需要消耗大量的CPU資源

互斥鎖的使用前提:多條線程搶奪同一塊資源

相關(guān)專業(yè)術(shù)語:線程同步
線程同步的意思是:多條線程按順序地執(zhí)行任務(wù)
互斥鎖,就是使用了線程同步技術(shù)

2.atomic和nonatomic
<1>OC在定義屬性時(shí)有nonatomic和atomic兩種選擇
自旋鎖:
atomic:原子屬性,為setter方法加鎖(默認(rèn)就是atomic)
nonatomic:非原子屬性,不會為setter方法加鎖

<2>nonatomic和atomic對比
atomic:線程安全,需要消耗大量的資源
nonatomic:非線程安全,適合內(nèi)存小的移動設(shè)備

<3>自旋鎖與互斥鎖的異同:
互斥鎖:@synchronized(){}
自旋鎖:atomic修飾的屬性,set方法中會添加自旋鎖
共同點(diǎn):當(dāng)多個(gè)線程訪問同一個(gè)資源的時(shí)候,通過加鎖可以避免數(shù)據(jù)安全問題。
不同點(diǎn):互斥鎖,其他線程(除了當(dāng)前正在訪問數(shù)據(jù)的其他想要訪問這個(gè)數(shù)據(jù)的線程)會處于阻塞狀態(tài)(有一個(gè)再回到就緒狀態(tài)的過程);自旋鎖,其他線程處于無限循環(huán)的過程(不會有狀態(tài)的改變)

<4>iOS開發(fā)的建議
所有屬性都聲明為nonatomic
盡量避免多線程搶奪同一塊資源
盡量將加鎖、資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器端處理,減小移動客戶端的壓力

3.線程間通信

<1>什么叫做線程間通信
在1個(gè)進(jìn)程中,線程往往不是孤立存在的,多個(gè)線程之間需要經(jīng)常進(jìn)行通信

<2>線程間通信的體現(xiàn)
1個(gè)線程傳遞數(shù)據(jù)給另1個(gè)線程
在1個(gè)線程中執(zhí)行完特定任務(wù)后,轉(zhuǎn)到另1個(gè)線程繼續(xù)執(zhí)行任務(wù)

<3>線程間通信常用方法

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

4.GCD

<1>什么是GCD
1.全稱是Grand Central Dispatch,可譯為“牛逼的中樞調(diào)度器”
2.純C語言,提供了非常多強(qiáng)大的函數(shù)
<2>GCD的優(yōu)勢
1.GCD是蘋果公司為多核的并行運(yùn)算提出的解決方案
2.GCD會自動利用更多的CPU內(nèi)核(比如雙核、四核)
3.GCD會自動管理線程的聲明周期(創(chuàng)建線程、調(diào)度任務(wù)、銷毀線程)
4.程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼
<3>GCD的兩個(gè)核心概念
1.任務(wù);執(zhí)行什么操作
2.隊(duì)列:用來存放任務(wù)
<4>使用步驟
1.定制任務(wù):確定想要做的事情
2.將任務(wù)添加到隊(duì)列中

  • GCD會自動將隊(duì)列中的任務(wù)取出,放到對應(yīng)的線程中執(zhí)行
  • 任務(wù)的取出遵循隊(duì)列的FIFO原則:先進(jìn)先出,后進(jìn)后出

<5>GCD中有2個(gè)用來執(zhí)行任務(wù)的函數(shù)
1.用同步的方式執(zhí)行任務(wù)

dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
  • queue:隊(duì)列
  • block:任務(wù)

2.用異步的方式執(zhí)行任務(wù)

dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

3.同步和異步的區(qū)別

  • 同步:在當(dāng)前線程中執(zhí)行,必須馬上執(zhí)行任務(wù)
  • 異步:在另一條線程中執(zhí)行,可以延時(shí)執(zhí)行

<6>GCD的隊(duì)列可以分為2大類型
1.并發(fā)隊(duì)列(Concurrent Dispatch Queue)

  • 可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))
  • 并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效

2.串行隊(duì)列(Serial Dispatch Queue)

  • 讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù))

<7>有4個(gè)術(shù)語比較容易混淆:同步、異步、并發(fā)、串行
1.同步和異步?jīng)Q定了要不要開啟新的線程

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

2.并發(fā)和串行決定了任務(wù)的執(zhí)行方式

  • 并發(fā):多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行
  • 串行:一個(gè)任務(wù)執(zhí)行完畢后,再執(zhí)行下一個(gè)任務(wù)

3.在UI中當(dāng)前線程雙核主線程,即同步是在主線程中執(zhí)行任務(wù)的,而異步是在開辟子線程中執(zhí)行任務(wù)

<8>并發(fā)(并行)隊(duì)列
1.GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列,供整個(gè)應(yīng)用使用,不需要手動創(chuàng)建

使用dispatch_get_global_queue函數(shù)獲得全局的并發(fā)隊(duì)列
dispatch_queue_t dispatch_get_global_queue(
dispatch_queue_priority_t priority, // 隊(duì)列的優(yōu)先級
unsigned long flags); // 此參數(shù)暫時(shí)無用,用0即可
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 獲得全局并發(fā)隊(duì)列

2.全局并發(fā)隊(duì)列的優(yōu)先級

#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺

3.手動創(chuàng)建并行隊(duì)列

dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL);

<9>GCD中獲得串行有2種途徑

1.使用dispatch_queue_create函數(shù)創(chuàng)建串行隊(duì)列
dispatch_queue_t
dispatch_queue_create(const char *label, // 隊(duì)列名稱 
dispatch_queue_attr_t attr); // 隊(duì)列屬性,一般用NULL即可
dispatch_queue_t queue = dispatch_queue_create("cn.qianfeng.queue", NULL); // 創(chuàng)建
dispatch_release(queue); // 非ARC需要釋放手動創(chuàng)建的隊(duì)列

2.使用主隊(duì)列(跟主線程相關(guān)聯(lián)的隊(duì)列)

主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列
放在主隊(duì)列中的任務(wù),都會放到主線程中執(zhí)行
使用dispatch_get_main_queue()獲得主隊(duì)列
dispatch_queue_t queue = dispatch_get_main_queue();

<10>各種隊(duì)列的執(zhí)行效果

column column
全局并行隊(duì)列 手動創(chuàng)建創(chuàng)建串行隊(duì)列 主隊(duì)列
同步(sync) 沒有開啟新線程;串行執(zhí)行任務(wù) 沒有開啟新線程;串行執(zhí)行任務(wù) 會死鎖
異步(async) 有開啟新線程;并行執(zhí)行任務(wù) 有開啟新線程;串行執(zhí)行任務(wù) 沒有開啟新線程;串行執(zhí)行任務(wù)

<11>從子線程回到主線程

dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 執(zhí)行耗時(shí)的異步操作...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主線程,執(zhí)行UI刷新操作
        });
});

<12>延時(shí)執(zhí)行
1.iOS常見的延時(shí)執(zhí)行有2種方式

調(diào)用NSObject的方法
[self performSelector:@selector(run) withObject:nil afterDelay:2.0];
// 2秒后再調(diào)用self的run方法

2.使用GCD函數(shù)

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 2秒后異步執(zhí)行這里的代碼...
});

<13>一次性代碼
使用dispatch_once函數(shù)能保證某段代碼在程序運(yùn)行過程中只被執(zhí)行1次

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    // 只執(zhí)行1次的代碼(這里面默認(rèn)是線程安全的)
    //可用于UI中創(chuàng)建單例
});

<14>隊(duì)列組
1.有這么1種需求

  • 首先:分別異步執(zhí)行2個(gè)耗時(shí)的操作
  • 其次:等2個(gè)異步操作都執(zhí)行完畢后,再回到主線程執(zhí)行操作

2.如果想要快速高效地實(shí)現(xiàn)上述需求,可以考慮用隊(duì)列組

dispatch_group_t group =  dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 執(zhí)行1個(gè)耗時(shí)的異步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 執(zhí)行1個(gè)耗時(shí)的異步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // 等前面的異步操作都執(zhí)行完畢后,回到主線程...
});

5.NSOperation

<1>NSOperation的作用
1.配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線程編程

2.NSOperation和NSOperationQueue實(shí)現(xiàn)多線程的具體步驟

  • 先將需要執(zhí)行的操作封裝到一個(gè)NSOperation對象中
  • 然后將NSOperation對象添加到NSOperationQueue中
  • 系統(tǒng)會自動將NSOperationQueue中的NSOperation取出來
  • 將取出的NSOperation封裝的操作放到一條新線程中執(zhí)行

3.NSOperation是個(gè)抽象類,并不具備封裝操作的能力,必須使用它的子類

4.使用NSOperation子類的方式有3種

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

5.創(chuàng)建NSInvocationOperation對象

-(id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
  • 調(diào)用start方法開始執(zhí)行操作
 -(void)start;

一旦執(zhí)行操作,就會調(diào)用target的sel方法

注意:

  • 默認(rèn)情況下,調(diào)用了start方法后并不會開一條新線程去執(zhí)行操作,而是在當(dāng)前線程同步執(zhí)行操作
  • 只有將NSOperation放到一個(gè)NSOperationQueue中,才會異步執(zhí)行操作

6.創(chuàng)建NSBlockOperation對象

+(id)blockOperationWithBlock:(void (^)(void))block;
  • 通過addExecutionBlock:方法添加更多的操作
-(void)addExecutionBlock:(void (^)(void))block;
  • 注意:只要NSBlockOperation封裝的操作數(shù) > 1,就會異步執(zhí)行操作

<2>NSOperationQueue的作用
1.NSOperation可以調(diào)用start方法來執(zhí)行任務(wù),但默認(rèn)是同步執(zhí)行的
2.如果將NSOperation添加到NSOperationQueue(操作隊(duì)列)中,系統(tǒng)會自動異步執(zhí)行NSOperation中的操作

  • 添加操作到NSOperationQueue中
-(void); addOperation:(NSOperation *)op
-(void)addOperationWithBlock:(void (^)(void))block;

<3>什么是并發(fā)數(shù)
1.同時(shí)執(zhí)行的任務(wù)數(shù)
2.比如,同時(shí)開3個(gè)線程執(zhí)行3個(gè)任務(wù),并發(fā)數(shù)就是3

  • 最大并發(fā)數(shù)的相關(guān)方法
-(NSInteger)maxConcurrentOperationCount;
-(void)setMaxConcurrentOperationCount:(NSInteger)cnt;

<4>隊(duì)列的取消、暫停、恢復(fù)
1.取消隊(duì)列的所有操作

-(void)cancelAllOperations;
提示:也可以調(diào)用NSOperation的- (void)cancel方法取消單個(gè)操作

2.暫停和恢復(fù)隊(duì)列

-(void)setSuspended:(BOOL)b; // YES代表暫停隊(duì)列,NO代表恢復(fù)隊(duì)列
-(BOOL)isSuspended;

<5>操作優(yōu)先級
1.設(shè)置NSOperation在queue中的優(yōu)先級,可以改變操作的執(zhí)行優(yōu)先級

-(NSOperationQueuePriority)queuePriority;
-(void)setQueuePriority:(NSOperationQueuePriority)p;

2.優(yōu)先級的取值

NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8

<6>操作的監(jiān)聽
可以監(jiān)聽一個(gè)操作的執(zhí)行完畢

-(void (^)(void))completionBlock;
-(void)setCompletionBlock:(void (^)(void))block;

<7>操作依賴
1.NSOperation之間可以設(shè)置依賴來保證執(zhí)行順序

  • 比如一定要讓操作A執(zhí)行完后,才能執(zhí)行操作B,可以這么寫
[operationB addDependency:operationA]; // 操作B依賴于操作A

2.可以在不同queue的NSOperation之間創(chuàng)建依賴關(guān)系
3.注意:不能相互依賴

  • 比如A依賴B,B依賴A

<8>自定義NSOperation
1.自定義NSOperation的步驟很簡單

  • 重寫- (void)main方法,在里面實(shí)現(xiàn)想執(zhí)行的任務(wù)

2.重寫- (void)main方法的注意點(diǎn)

  • 自己創(chuàng)建自動釋放池(因?yàn)槿绻钱惒讲僮?,無法訪問主線程的自動釋放池)
  • 經(jīng)常通過- (BOOL)isCancelled方法檢測操作是否被取消,對取消做出響應(yīng)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評論 2 373

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

  • 什么是進(jìn)程? 進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序。 每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存...
    珍此良辰閱讀 1,264評論 1 5
  • 多線程 在iOS開發(fā)中為提高程序的運(yùn)行效率會將比較耗時(shí)的操作放在子線程中執(zhí)行,iOS系統(tǒng)進(jìn)程默認(rèn)啟動一個(gè)主線程,用...
    郭豪豪閱讀 2,608評論 0 4
  • .一.進(jìn)程 進(jìn)程:是指在系統(tǒng)中正在運(yùn)行的一個(gè)應(yīng)用程序,每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空...
    IIronMan閱讀 4,508評論 1 33
  • 歡迎大家指出文章中需要改正或者需要補(bǔ)充的地方,我會及時(shí)更新,非常感謝。 一. 多線程基礎(chǔ) 1. 進(jìn)程 進(jìn)程是指在系...
    xx_cc閱讀 7,223評論 11 70
  • 定語從句是在英語文章中很常見的從句類型,比如讀英文版《Alice in Wonderland》時(shí),僅僅是which...
    云朵里的汪閱讀 911評論 12 7