【iOS】多線程1--NSThread

1礁阁、簡介:

1.1 iOS有三種多線程編程的技術(shù)猎塞,分別是:

1.诗舰、NSThread

2、Cocoa NSOperationiOS多線程編程之NSOperation和NSOperationQueue的使用

3竿奏、GCD全稱:Grand Central Dispatch(iOS多線程編程之Grand Central Dispatch(GCD)介紹和使用

這三種編程方式從上到下,抽象度層次是從低到高的腥放,抽象度越高的使用越簡單泛啸,也是Apple最推薦使用的。

這篇我們主要介紹和使用NSThread秃症,后面會繼續(xù)2候址、3 的講解和使用吕粹。

1.2 三種方式的有缺點(diǎn)介紹:

NSThread:

優(yōu)點(diǎn):NSThread 比其他兩個輕量級

缺點(diǎn):需要自己管理線程的生命周期,線程同步岗仑。線程同步對數(shù)據(jù)的加鎖會有一定的系統(tǒng)開銷

NSThread實(shí)現(xiàn)的技術(shù)有下面三種:

Technology

Description

Cocoa threads

Cocoa implements threads using theNSThreadclass. Cocoa also provides methods onNSObjectfor spawning new threads and executing code on already-running threads. For more information, see“Using NSThread”and“Using NSObject to Spawn a Thread.”

POSIX threads

POSIX threads provide a C-based interface for creating threads. If you are not writing a Cocoa application, this is the best choice for creating threads. The POSIX interface is relatively simple to use and offers ample flexibility for configuring your threads. For more information, see“Using POSIX Threads”

Multiprocessing Services

Multiprocessing Services is a legacy C-based interface used by applications transitioning from older versions of Mac OS. This technology is available in OS X only and should be avoided for any new development. Instead, you should use theNSThreadclass or POSIX threads. If you need more information on this technology, seeMultiprocessing Services Programming Guide.

一般使用cocoa thread 技術(shù)匹耕。

Cocoa operation

優(yōu)點(diǎn):不需要關(guān)心線程管理,數(shù)據(jù)同步的事情荠雕,可以把精力放在自己需要執(zhí)行的操作上稳其。

Cocoa operation 相關(guān)的類是?NSOperation ,NSOperationQueue炸卑。NSOperation是個抽象類既鞠,使用它必須用它的子類,可以實(shí)現(xiàn)它或者使用它定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation盖文。創(chuàng)建NSOperation子類的對象嘱蛋,把對象添加到NSOperationQueue隊(duì)列里執(zhí)行。

GCD

Grand Central Dispatch (GCD)是Apple開發(fā)的一個多核編程的解決方法五续。在iOS4.0開始之后才能使用洒敏。GCD是一個替代諸如NSThread, NSOperationQueue, NSInvocationOperation等技術(shù)的很高效和強(qiáng)大的技術(shù)。現(xiàn)在的iOS系統(tǒng)都升級到6了疙驾,所以不用擔(dān)心該技術(shù)不能使用凶伙。

介紹完這三種多線程編程方式,我們這篇先介紹NSThread的使用荆萤。

2镊靴、NSThread的使用

2.1 NSThread 有兩種直接創(chuàng)建方式:

- (id)initWithTarget:(id)targetselector:(SEL)selectorobject:(id)argument

+ (void)detachNewThreadSelector:(SEL)aSelectortoTarget:(id)aTargetwithObject:(id)anArgument

第一個是實(shí)例方法,第二個是類方法

[cpp]view plaincopy

1链韭、[NSThread?detachNewThreadSelector:@selector(doSomething:)?toTarget:self?withObject:nil];

2偏竟、NSThread*?myThread?=?[[NSThread?alloc]?initWithTarget:self

selector:@selector(doSomething:)

object:nil];

[myThread?start];

2.2參數(shù)的意義:

selector :線程執(zhí)行的方法,這個selector只能有一個參數(shù)敞峭,而且不能有返回值踊谋。

target ?:selector消息發(fā)送的對象

argument:傳輸給target的唯一參數(shù),也可以是nil

第一種方式會直接創(chuàng)建線程并且開始運(yùn)行線程旋讹,第二種方式是先創(chuàng)建線程對象殖蚕,然后再運(yùn)行線程操作,在運(yùn)行線程操作前可以設(shè)置線程的優(yōu)先級等線程信息

2.3 PS:不顯式創(chuàng)建線程的方法:

用NSObject的類方法 ?performSelectorInBackground:withObject: 創(chuàng)建一個線程:

[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];

2.4 下載圖片的例子:

2.4.1 ?新建singeView app

新建項(xiàng)目沉迹,并在xib文件上放置一個imageView控件睦疫。按住control鍵拖到viewControll

er.h文件中創(chuàng)建imageView IBOutlet

ViewController.m中實(shí)現(xiàn):

[cpp]view plaincopy

//

//??ViewController.m

//??NSThreadDemo

//

//??Created?by?rongfzh?on?12-9-23.

//??Copyright?(c)?2012年?rongfzh.?All?rights?reserved.

//

#import?"ViewController.h"

#define?kURL?@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"

@interface?ViewController?()

@end

@implementation?ViewController

-(void)downloadImage:(NSString?*)?url{

NSData?*data?=?[[NSData?alloc]?initWithContentsOfURL:[NSURL?URLWithString:url]];

UIImage?*image?=?[[UIImage?alloc]initWithData:data];

if(image?==?nil){

}else{

[self?performSelectorOnMainThread:@selector(updateUI:)?withObject:image?waitUntilDone:YES];

}

}

-(void)updateUI:(UIImage*)?image{

self.imageView.image?=?image;

}

-?(void)viewDidLoad

{

[super?viewDidLoad];

//????[NSThread?detachNewThreadSelector:@selector(downloadImage:)?toTarget:self?withObject:kURL];

NSThread?*thread=?[[NSThread?alloc]initWithTarget:self?selector:@selector(downloadImage:)?object:kURL];

[threadstart];

}

-?(void)didReceiveMemoryWarning

{

[super?didReceiveMemoryWarning];

//?Dispose?of?any?resources?that?can?be?recreated.

}

@end

2.4.2線程間通訊

線程下載完圖片后怎么通知主線程更新界面呢?

[selfperformSelectorOnMainThread:@selector(updateUI:)withObject:imagewaitUntilDone:YES];

performSelectorOnMainThread是NSObject的方法鞭呕,除了可以更新主線程的數(shù)據(jù)外蛤育,還可以更新其他線程的比如:

用:performSelector:onThread:withObject:waitUntilDone:

運(yùn)行下載圖片:

圖片下載下來了。

2.3 線程同步

我們演示一個經(jīng)典的賣票的例子來講NSThread的線程同步:

.h

[cpp]view plaincopy

#import?

@classViewController;

@interface?AppDelegate?:?UIResponder?

{

inttickets;

intcount;

NSThread*?ticketsThreadone;

NSThread*?ticketsThreadtwo;

NSCondition*?ticketsCondition;

NSLock?*theLock;

}

@property?(strong,?nonatomic)?UIWindow?*window;

@property?(strong,?nonatomic)?ViewController?*viewController;

@end

[cpp]view plaincopy

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

{

tickets?=?100;

count?=?0;

theLock?=?[[NSLock?alloc]?init];

//?鎖對象

ticketsCondition?=?[[NSCondition?alloc]?init];

ticketsThreadone?=?[[NSThread?alloc]?initWithTarget:self?selector:@selector(run)?object:nil];

[ticketsThreadone?setName:@"Thread-1"];

[ticketsThreadone?start];

ticketsThreadtwo?=?[[NSThread?alloc]?initWithTarget:self?selector:@selector(run)?object:nil];

[ticketsThreadtwo?setName:@"Thread-2"];

[ticketsThreadtwo?start];

self.window?=?[[UIWindow?alloc]?initWithFrame:[[UIScreen?mainScreen]?bounds]];

//?Override?point?for?customization?after?application?launch.

self.viewController?=?[[ViewController?alloc]?initWithNibName:@"ViewController"bundle:nil];

self.window.rootViewController?=?self.viewController;

[self.window?makeKeyAndVisible];

returnYES;

}

-?(void)run{

while(TRUE)?{

//?上鎖

//????????[ticketsCondition?lock];

[theLock?lock];

if(tickets?>=?0){

[NSThread?sleepForTimeInterval:0.09];

count?=?100?-?tickets;

NSLog(@"當(dāng)前票數(shù)是:%d,售出:%d,線程名:%@",tickets,count,[[NSThread?currentThread]?name]);

tickets--;

}else{

break;

}

[theLock?unlock];

//????????[ticketsCondition?unlock];

}

}

如果沒有線程同步的lock,賣票數(shù)可能是-1.加上lock之后線程同步保證了數(shù)據(jù)的正確性瓦糕。

上面例子我使用了兩種鎖底洗,一種NSCondition ,一種是:NSLock咕娄。 NSCondition我已經(jīng)注釋了亥揖。

線程的順序執(zhí)行

他們都可以通過

[ticketsConditionsignal]; 發(fā)送信號的方式,在一個線程喚醒另外一個線程的等待圣勒。

比如:

[cpp]view plaincopy

#import?"AppDelegate.h"

#import?"ViewController.h"

@implementation?AppDelegate

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

{

tickets?=?100;

count?=?0;

theLock?=?[[NSLock?alloc]?init];

//?鎖對象

ticketsCondition?=?[[NSCondition?alloc]?init];

ticketsThreadone?=?[[NSThread?alloc]?initWithTarget:self?selector:@selector(run)?object:nil];

[ticketsThreadone?setName:@"Thread-1"];

[ticketsThreadone?start];

ticketsThreadtwo?=?[[NSThread?alloc]?initWithTarget:self?selector:@selector(run)?object:nil];

[ticketsThreadtwo?setName:@"Thread-2"];

[ticketsThreadtwo?start];

NSThread?*ticketsThreadthree?=?[[NSThread?alloc]?initWithTarget:self?selector:@selector(run3)?object:nil];

[ticketsThreadthree?setName:@"Thread-3"];

[ticketsThreadthree?start];

self.window?=?[[UIWindow?alloc]?initWithFrame:[[UIScreen?mainScreen]?bounds]];

//?Override?point?for?customization?after?application?launch.

self.viewController?=?[[ViewController?alloc]?initWithNibName:@"ViewController"bundle:nil];

self.window.rootViewController?=?self.viewController;

[self.window?makeKeyAndVisible];

returnYES;

}

-(void)run3{

while(YES)?{

[ticketsCondition?lock];

[NSThread?sleepForTimeInterval:3];

[ticketsCondition?signal];

[ticketsCondition?unlock];

}

}

-?(void)run{

while(TRUE)?{

//?上鎖

[ticketsCondition?lock];

[ticketsCondition?wait];

[theLock?lock];

if(tickets?>=?0){

[NSThread?sleepForTimeInterval:0.09];

count?=?100?-?tickets;

NSLog(@"當(dāng)前票數(shù)是:%d,售出:%d,線程名:%@",tickets,count,[[NSThread?currentThread]?name]);

tickets--;

}else{

break;

}

[theLock?unlock];

[ticketsCondition?unlock];

}

}

wait是等待费变,我加了一個 線程3 去喚醒其他兩個線程鎖中的wait

其他同步

我們可以使用指令 @synchronized 來簡化 NSLock的使用,這樣我們就不必顯示編寫創(chuàng)建NSLock,加鎖并解鎖相關(guān)代碼灾而。

- (void)doSomeThing:(id)anObj

{

@synchronized(anObj)

{

// Everything between the braces is protected by the @synchronized directive.

}

}

還有其他的一些鎖對象胡控,比如:循環(huán)鎖NSRecursiveLock,條件鎖NSConditionLock旁趟,分布式鎖NSDistributedLock等等,可以自己看官方文檔學(xué)習(xí)

NSThread下載圖片的例子代碼:http://download.csdn.net/detail/totogo2010/4591149

著作權(quán)聲明:本文由http://blog.csdn.net/totogo2010/原創(chuàng)昼激,歡迎轉(zhuǎn)載分享。請尊重作者勞動锡搜,轉(zhuǎn)載時保留該聲明和作者博客鏈接橙困,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市耕餐,隨后出現(xiàn)的幾起案子凡傅,更是在濱河造成了極大的恐慌,老刑警劉巖肠缔,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夏跷,死亡現(xiàn)場離奇詭異,居然都是意外死亡明未,警方通過查閱死者的電腦和手機(jī)槽华,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趟妥,“玉大人猫态,你說我怎么就攤上這事∨悖” “怎么了亲雪?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長疚膊。 經(jīng)常有香客問我义辕,道長,這世上最難降的妖魔是什么寓盗? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任终息,我火速辦了婚禮夺巩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘周崭。我一直安慰自己,他們只是感情好喳张,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布续镇。 她就那樣靜靜地躺著,像睡著了一般销部。 火紅的嫁衣襯著肌膚如雪摸航。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天舅桩,我揣著相機(jī)與錄音酱虎,去河邊找鬼。 笑死擂涛,一個胖子當(dāng)著我的面吹牛读串,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播撒妈,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼恢暖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狰右?” 一聲冷哼從身側(cè)響起杰捂,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棋蚌,沒想到半個月后嫁佳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谷暮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年蒿往,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坷备。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡熄浓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出省撑,到底是詐尸還是另有隱情赌蔑,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布竟秫,位于F島的核電站娃惯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏肥败。R本人自食惡果不足惜趾浅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一愕提、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧皿哨,春花似錦浅侨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至央勒,卻和暖如春不见,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背崔步。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工稳吮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人井濒。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓灶似,卻偏偏與公主長得像,于是被迫代替她去往敵國和親眼虱。 傳聞我的和親對象是個殘疾皇子喻奥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

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

  • 1、簡介:1.1 iOS有三種多線程編程的技術(shù)捏悬,分別是:1.撞蚕、NSThread2、Cocoa NSOperatio...
    LuckTime閱讀 1,348評論 0 1
  • 原文出處:容芳志的博客 簡介 iOS有三種多線程編程的技術(shù)刀疙,分別是: (一)NSThread (二)Cocoa N...
    sky_kYU閱讀 608評論 0 1
  • 原文出處:容芳志的博客 簡介 iOS有三種多線程編程的技術(shù),分別是: (一)NSThread(二)Cocoa NS...
    Asserts閱讀 448評論 0 0
  • 一扫倡、多線程基礎(chǔ) 基本概念 進(jìn)程進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序每個進(jìn)程之間是獨(dú)立的谦秧,每個進(jìn)程均運(yùn)行在其專用且...
    AlanGe閱讀 546評論 0 0
  • 人們總說大學(xué)是美好的,到了大學(xué)就到了天堂撵溃。父母說好好學(xué)習(xí)疚鲤,老師說,再刻苦些…… 時光荏苒缘挑,我已到了大學(xué)集歇,可是我...
    夏日的花香閱讀 162評論 1 2