iOS多線程編程入門

進(jìn)程 線程

  • 進(jìn)程占據(jù)內(nèi)存,而線程占據(jù)CPU。一個(gè)進(jìn)程可以有多個(gè)線程,進(jìn)程之間可以通過管道 或者套接字(Socket)進(jìn)行通信,而在一個(gè)進(jìn)程中,多個(gè)線程相互之間可以直接 很方便的進(jìn)行通信。使用多線程編程可以幫助我們的程序減少 程序出現(xiàn)卡頓 假死這些情況的出現(xiàn)(不阻塞主線程的執(zhí)行),使用起來可以極大的提升程序的用戶體驗(yàn),但是多線程也有一個(gè)不好的地方在于,你線程開得多了,對(duì)于其他進(jìn)程來說就是一個(gè)不好的事情,其他進(jìn)程占用的資源就會(huì)變少。所以我們?cè)谑褂枚嗑€程編程編程的時(shí)候要注意這點(diǎn)問題。

  • 下面是一個(gè)使用多線程中NSOperation 的一個(gè)例子:

    兩個(gè)按鈕模擬多線程 一個(gè)按鈕點(diǎn)擊以后會(huì)睡眠10秒鐘 再執(zhí)行的響應(yīng)的內(nèi)容 另外一個(gè)按鈕點(diǎn)擊以后就會(huì)執(zhí)行相應(yīng)的內(nèi)容 但是不適用多線程編程的時(shí)候 你點(diǎn)擊了有睡眠的按鈕 第二個(gè)就不能點(diǎn)擊了 因?yàn)榈诙€(gè)要等待第一個(gè)按鈕完成它的全部事件以后才會(huì)執(zhí)行 這樣就造成了程序了卡頓 或者假死 所以這也是其我們要使用多線程編程的原因。

代碼區(qū)##

#import<UIKit/UIKit.h>

@interface ViewController : UIViewController

@end


#import<UIKit/UIKit.h>

@interface ViewController ()

@end

@implementation ViewController 

- (void)viewDidLoad {

[super viewDidLoad];

}

- (void) foo:(UIButton *) button {

// 休眠和退出都是只有正在執(zhí)行的線程可以調(diào)用的方法

// 因此在設(shè)計(jì)上這兩個(gè)方法都是類方法而不是對(duì)象方法

// [NSThread exit];

// [NSThread sleepForTimeInterval:10]; 的作用和sleep(10)是一樣的

sleep(10);

NSLog(@"任務(wù)1已經(jīng)完成!");

// 提示: 刷新界面的操作要回到主線程處理否則有可能失效

// [self performSelectorOnMainThread:@selector(bar:) withObject:button waitUntilDone:YES];

// 創(chuàng)建一個(gè)操作對(duì)象

NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(bar:) object:button];

// 向主線程隊(duì)列中添加操作對(duì)象(操作放到主線程中執(zhí)行)

[[NSOperationQueue mainQueue] addOperation:op];

}

//刷新界面以后 讓按鈕又可以再點(diǎn)擊  讓按鈕的文字恢復(fù)

- (void) bar:(UIButton *) button {

button.enabled = YES;

[button setTitle:@"任務(wù)1" forState:UIControlStateNormal];

}

- (IBAction)blueButtonClicked:(UIButton *)sender {

// 提示: 對(duì)于那些耗時(shí)間的任務(wù)基本上都應(yīng)該放到其他的執(zhí)行線程中

// 不要阻塞主線程的執(zhí)行 否則界面會(huì)出現(xiàn)卡頓或假死現(xiàn)象

// 模擬任務(wù)需要執(zhí)行10秒鐘

[sender setTitle:@"正在執(zhí)行..." forState:UIControlStateNormal];

sender.enabled = NO;

// 創(chuàng)建一個(gè)操作對(duì)象(待會(huì)要將該操作放到一個(gè)隊(duì)列中去執(zhí)行)

NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{

[self foo:sender];

}];

// 創(chuàng)建一個(gè)并發(fā)隊(duì)列

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 設(shè)置最大并發(fā)數(shù)量

queue.maxConcurrentOperationCount = 5;

// 向隊(duì)列中添加一個(gè)操作

[queue addOperation:op];

// [NSThread detachNewThreadSelector:@selector(foo:) toTarget:self withObject:sender];

// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(foo:) object:sender];

// 啟動(dòng)線程(執(zhí)行foo回調(diào)方法)

// [thread start];

// sleep(1);

// 提示: 如果線程已經(jīng)開始執(zhí)行則無法取消  --->如果不執(zhí)行前面的那個(gè)sleep(1)   線程可以被取消但是 執(zhí)行了sleep(1)以后線程就無法被取消了。

// [thread cancel];

// [self performSelectorInBackground:@selector(foo:) withObject:sender];

}

- (IBAction)yellowButtonClicked:(UIButton *)sender {

NSLog(@"任務(wù)2已經(jīng)完成!");

}

@end

補(bǔ)充說明:
補(bǔ)充一點(diǎn): 如果我們的程序中 出現(xiàn)了多個(gè)線程競(jìng)爭(zhēng)同一個(gè)資源的情況,這個(gè)時(shí)候 我們需要對(duì)這個(gè)資源進(jìn)行同步保護(hù)(synchronized) 讓線程處于一個(gè)排隊(duì)狀態(tài) ,當(dāng)一個(gè)線程進(jìn)入執(zhí)行的時(shí)候,鎖被鎖上,然后其他進(jìn)程無法進(jìn)入。直到該線程完成了它的工作以后,它就會(huì)出來 然后鎖就會(huì)被打開 然后其他線程就接著一個(gè)一個(gè)的執(zhí)行。當(dāng)然一個(gè)完成以后 另外一個(gè)進(jìn)入的時(shí)候 并不是有順序排好隊(duì)的進(jìn)入 就好比哪個(gè)運(yùn)氣好 哪個(gè)就先進(jìn)去。

  • 舉例說明:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//創(chuàng)建一個(gè)可變字符串作為多個(gè)線程共同競(jìng)爭(zhēng)的一個(gè)資源

NSMutableString *mStr = [NSMutableString stringWithCapacity:10000];

//創(chuàng)建5個(gè)線程模擬競(jìng)爭(zhēng)同一個(gè)資源

for(int i = 0;i < 5; i++){

[NSThread detachNewThreadSelector:@selector(foo:) toTarget:self withObject:mStr];

}

return YES;

}

-(void)foo:(NSMutableString *)mStr{

for(int i = 0; i < 10000;i++){

@synchronized(mStr){

[mStr appendString:@"a"];

                            }

                   }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,881評(píng)論 25 709
  • 又來到了一個(gè)老生常談的問題,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢? 今天就這個(gè)問題開始,來談?wù)劜?..
    tangsl閱讀 4,317評(píng)論 0 23
  • Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼,方法是什么?如果想延時(shí)執(zhí)行代碼、方法又是什么? 1...
    AlanGe閱讀 1,913評(píng)論 0 17
  • 周三 晴 讀經(jīng)照舊 今晚有舞蹈課,媽媽叮囑爸爸,放學(xué)回家后讓橙子先把數(shù)學(xué)作業(yè)做了。這樣晚上跳舞回來可以早點(diǎn)休息。今...
    圣鳳閱讀 407評(píng)論 0 0
  • 覺察日記+6月30日+乾珉+反6 我家那貨最近吃完飯就把碗筷鍋的扔在那里,不管,我就很生氣,我要是吃的話我把廚房收...
    乾珉閱讀 145評(píng)論 0 0

友情鏈接更多精彩內(nèi)容