名單
多線程在各種編程語(yǔ)言中都是難點(diǎn),很多語(yǔ)言中實(shí)現(xiàn)起來(lái)很麻煩,objective-c雖然源于c,但其多線程編程卻相當(dāng)簡(jiǎn)單,可以與java相媲美。這篇文章主要從線程創(chuàng)建與啟動(dòng)、線程的同步與鎖、線程的交互、線程池等等四個(gè)方面簡(jiǎn)單的講解一下iphone中的多線程編程。
一、線程創(chuàng)建與啟動(dòng)
線程創(chuàng)建主要有二種方式:
- (id)init; // designated initializer
- (id)initwithtarget:(id)target selector:(sel)selector object:(id)argument;當(dāng)然,還有一種比較特殊,就是使用所謂的convenient method,這個(gè)方法可以直接生成一個(gè)線程并啟動(dòng)它,而且無(wú)需為線程的清理負(fù)責(zé)。這個(gè)方法的接口是:
+ (void)detachnewthreadselector:(sel)aselector totarget:(id)atarget withobject:(id)anargument前兩種方法創(chuàng)建后,需要手機(jī)啟動(dòng),啟動(dòng)的方法是:
- (void)start;
二、線程的同步與鎖
要說(shuō)明線程的同步與鎖,最好的例子可能就是多個(gè)窗口同時(shí)售票的售票系統(tǒng)了。我們知道在java中,使用synchronized來(lái)同步,而iphone雖然沒(méi)有提供類似java下的synchronized關(guān)鍵字,但提供了nscondition對(duì)象接口。查看nscondition的接口說(shuō)明可以看出,nscondition是iphone下的鎖對(duì)象,所以我們可以使用nscondition實(shí)現(xiàn)iphone中的線程安全。這是來(lái)源于網(wǎng)上的一個(gè)例子:
sellticketsappdelegate.h 文件
// sellticketsappdelegate.h
import
@interface sellticketsappdelegate : nsobject {
int tickets;
int count;
nsthread* ticketsthreadone;
nsthread* ticketsthreadtwo;
nscondition* ticketscondition;
uiwindow *window;
}
@property (nonatomic, retain) iboutlet uiwindow *window;
@end
sellticketsappdelegate.m 文件
// sellticketsappdelegate.m
import sellticketsappdelegate.h
@implementation sellticketsappdelegate
@synthesize window;
- (void)applicationdidfinishlaunching:(uiapplication *)application {
tickets = 100;
count = 0;
// 鎖對(duì)象
ticketcondition = [[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 detachnewthreadselector:@selector(run) totarget:self withobject:nil];
// override point for customization after application launch
[window makekeyandvisible];
}
- (void)run{
while (true) {
// 上鎖
[ticketscondition lock];
if(tickets > 0){
[nsthread sleepfortimeinterval:0.5];
count = 100 - tickets;
nslog(@當(dāng)前票數(shù)是:%d,售出:%d,線程名:%@,tickets,count,[[nsthread currentthread] name]);
tickets--;
}else{
break;
}
[ticketscondition unlock];
}
}
- (void)dealloc {
[ticketsthreadone release];
[ticketsthreadtwo release];
[ticketscondition release];
[window release];
[super dealloc];
}
@end
三、線程的交互
線程在運(yùn)行過(guò)程中,可能需要與其它線程進(jìn)行通信,如在主線程中修改界面等等,可以使用如下接口:
- (void)performselectoronmainthread:(sel)aselector withobject:(id)arg waituntildone:(bool)wait
由于在本過(guò)程中,可能需要釋放一些資源,則需要使用nsautoreleasepool來(lái)進(jìn)行管理,如:
- (void)startthebackgroundjob {
nsautoreleasepool *pool = [[nsautoreleasepool alloc] init];
// to do something in your thread job
...
[self performselectoronmainthread:@selector(makemyprogressbarmoving) withobject:nil waituntildone:no];
[pool release];
}
如果你什么都不考慮,在線程函數(shù)內(nèi)調(diào)用 autorelease 、那么會(huì)出現(xiàn)下面的錯(cuò)誤:
nsautoreleasenopool(): object 0x********* of class nsconretedata autoreleased with no pool in place ….
四、關(guān)于線程池,大家可以查看nsoperation的相關(guān)資料
更多信息請(qǐng)查看IT技術(shù)專欄