多線程
程序:由源代碼生成的可執(zhí)行應(yīng)用。
進(jìn)程:一個(gè)正在運(yùn)行的程序可用看做一個(gè)進(jìn)程,進(jìn)程擁有獨(dú)立運(yùn)行所需要的全部資源。
線程:程序中獨(dú)立運(yùn)行的代碼段
iOS5之后子線程也有刷新UI的能力,但不夠快
iOS中關(guān)于UI的添加和刷新必須在主線程中操作
使用多線程開發(fā)的優(yōu)點(diǎn):
資源利用率更好,程序設(shè)計(jì)在某些情況下更簡(jiǎn)單,程序響應(yīng)更快
缺點(diǎn):
盡管提升了性能,但是存在一些訪問(wèn)限制,比如線程同步、線程互斥等,多線程在使用的時(shí)候,最終是要回到主線程刷新UI,如果開辟過(guò)多的多線程,會(huì)造成CPU的消耗
一、NSThread
每個(gè)線程都維護(hù)著自己對(duì)應(yīng)的NSAutoreleasePool對(duì)象,將其放在線程棧的棧頂。當(dāng)線程結(jié)束時(shí)會(huì)情況自動(dòng)釋放池
在應(yīng)用程序打開的是,系統(tǒng)會(huì)自動(dòng)為主線程創(chuàng)建一個(gè)自動(dòng)釋放池
我們收到創(chuàng)建的子線程需要我們手動(dòng)添加自動(dòng)釋放池
//1.輕量級(jí)別的多線程實(shí)現(xiàn)方式
//當(dāng)使用alloc init方式,需要我們手動(dòng)啟動(dòng),如果使用便利構(gòu)造器的方法,不需要手動(dòng)啟動(dòng)
//object 是線程回調(diào)方法的參數(shù),不需要就寫nil
NSThread *forThread = [[NSThread alloc]initWithTarget:self selector:@selector(aHundredMillion) object:nil];
//通過(guò)便利構(gòu)造器的方法創(chuàng)建Thread對(duì)象,不用手動(dòng)啟動(dòng)
[NSThread detachNewThreadSelector:@selector(thread_1Action:) toTarget:self withObject:@"thread_1"];
//為forThread命名
forThread.name = @"老二";
//線程優(yōu)先級(jí),當(dāng)優(yōu)先級(jí)越高,線程被先執(zhí)行的概率越高,0~1.0越來(lái)越高
forThread.threadPriority = 1.0;
//啟動(dòng)線程
[forThread start];
//得到當(dāng)前線程的信息
NSLog(@"iamgeThread--%@",[NSThread currentThread]);
//得到主線程的信息
NSLog(@"%@",[NSThread mainThread]);
//線程休眠
[NSThread sleepForTimeInterval:2];
//結(jié)束線程
//1.給線程發(fā)結(jié)束消息[forThread cancel];
//2.理解結(jié)束線程[NSThread exit];
//判斷線程是否在執(zhí)行[forThread isExecuting];
//判斷線程是否執(zhí)行完畢[forThread isFinished];
NSObject的多線程方法
//1.從主線程進(jìn)入子線程
[self performSelectorInBackground:@selector(objectThreadAction:) withObject:@"object開的子線程"];
//NSObject進(jìn)入子線程
-(void)objectThreadAction:(NSString*)sender
{
NSLog(@"%@",sender);
NSLog(@"%@",[NSThread currentThread]);
//從子線程回到主線程
//waitUnitDone:YES只有回主線程的回調(diào)方法執(zhí)行結(jié)束才會(huì)執(zhí)行下面的操作。NO:與之相反
[self performSelectorOnMainThread:@selector(backMainThread) withObject:nil waitUntilDone:YES];
NSLog(@"在回到主線程的底下");
}
線程鎖
@property (nonatomic,retain)NSLock *myLock;//線程鎖,當(dāng)多個(gè)線程同時(shí)訪問(wèn)同一資源的時(shí)候,對(duì)資源進(jìn)行保護(hù)
@property (nonatomic,assign)int ticket_Sum;//線程直接跳的總數(shù)
@end
@implementation ViewController
-(NSLock *)myLock
{
if (!_myLock) {
_myLock = [[NSLock alloc]init];
}
return _myLock;
}
//線程鎖學(xué)習(xí)
-(void)lock_study
{
@synchronized(self) {
//線程鎖,保證當(dāng)前只有一個(gè)線程在訪問(wèn)該資源
//將需要加鎖保護(hù)的代碼寫在花括號(hào)內(nèi)
}
//當(dāng)線程訪問(wèn)的是,加線程鎖
[self.myLock lock];
while (true) {
if (_ticket_Sum > 0)
{
_ticket_Sum--;
NSLog(@"剩余票=== %d",_ticket_Sum);
}
else
{
break;
}
}
//當(dāng)正在執(zhí)行的線程執(zhí)行完操作的時(shí)候,解鎖。其他線程可以訪問(wèn)
[self.myLock unlock];
}
二、NSOperation
NSOperation類,在MVC中屬于M,是用來(lái)封裝單個(gè)任務(wù)的相關(guān)代碼和數(shù)據(jù)的抽象類。
因?yàn)樗浅橄蟮?,不能直接使用這個(gè)類,而使用子類(NSInvocationOperation或NSBlockOperation)來(lái)執(zhí)行任務(wù)。
NsOperation,只是一個(gè)操作,本身無(wú)主線程子線程之分,可以在任意線程中使用,通常與NSOperationQueue結(jié)合使用
-(void)operation
{
//初始化一個(gè)任務(wù) target-action
NSInvocationOperation *invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction:) object:@"參數(shù)"];
//當(dāng)任務(wù)不在隊(duì)列中,需要手動(dòng)啟動(dòng)
[invocation start];
//操作block的方法
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
//實(shí)現(xiàn)我們需要做的操作
NSLog(@"block 當(dāng)前線程---%@",[NSThread currentThread]);
}];
//為block操作添加多個(gè)block執(zhí)行
//當(dāng)使用addExecutionBlock添加可執(zhí)行的block時(shí),這些block會(huì)在當(dāng)前線程或者其他子線程中進(jìn)行
for (int i = 0; i < 10; i++) {
[blockOperation addExecutionBlock:^{
NSLog(@"block2 當(dāng)前線程-- %@",[NSThread currentThread]);
}];
}
//最后執(zhí)行的block,此block會(huì)在最后執(zhí)行
blockOperation.completionBlock = ^()
{
NSLog(@"最后執(zhí)行的block-------%@",[NSThread currentThread]);
};
//all block must be before start
//啟動(dòng)操作
[blockOperation start];
NSLog(@"我在最下面");
}
把任務(wù)加入隊(duì)列當(dāng)中
//隊(duì)列quene NSOperationQuene是對(duì)GCD的OC級(jí)別的封裝
-(void)operationQuene
{
//先初始化隊(duì)列的對(duì)象,(其他隊(duì)列:出了主隊(duì)列,人為初始化的隊(duì)列都是其他隊(duì)列)
NSOperationQueue *otherQuene = [[NSOperationQueue alloc]init];
//設(shè)置最大并發(fā)數(shù),默認(rèn)為-1,可以無(wú)限個(gè),設(shè)置為1的時(shí)候,在同一時(shí)刻只能執(zhí)行一個(gè)操作
otherQuene.maxConcurrentOperationCount = 10;
for (int i = 0; i < 10; i++) {
//創(chuàng)建可執(zhí)行的操作對(duì)象
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"隊(duì)列-----當(dāng)前線程---%@--%d",[NSThread currentThread],i);
}];
if (i == 3) {
}
//將block操作添加到隊(duì)列中,當(dāng)操作對(duì)象添加到隊(duì)列中之后,就不需要手動(dòng)啟動(dòng)了
[otherQuene addOperation:blockOperation];
}
NSBlockOperation *blockOperation_0 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"隊(duì)列-----當(dāng)前線程---%@--%d",[NSThread currentThread],0);
}];
NSBlockOperation *blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"隊(duì)列-----當(dāng)前線程---%@--%d",[NSThread currentThread],1);
}];
NSBlockOperation *blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"隊(duì)列-----當(dāng)前線程---%@--%d",[NSThread currentThread],2);
}];
NSBlockOperation *blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"隊(duì)列-----當(dāng)前線程---%@--%d",[NSThread currentThread],3);
}];
NSBlockOperation *blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"隊(duì)列-----當(dāng)前線程---%@--%d",[NSThread currentThread],4);
}];
//為事件添加依賴關(guān)系,第四個(gè)必須在第三個(gè)后面執(zhí)行,這樣第四個(gè)任務(wù)一定在第三個(gè)執(zhí)行后,才會(huì)執(zhí)行
//要先添加依賴再講事件添加到隊(duì)列
[blockOperation_4 addDependency:blockOperation_3];
//添加進(jìn)隊(duì)列
[otherQuene addOperation:blockOperation_0];
[otherQuene addOperation:blockOperation_1];
[otherQuene addOperation:blockOperation_2];
[otherQuene addOperation:blockOperation_3];
[otherQuene addOperation:blockOperation_4];
}
添加到主隊(duì)列
//主隊(duì)列
-(void)operationMainQuene
{
NSLog(@"當(dāng)前線程--與主隊(duì)列無(wú)關(guān)--%@",[NSThread currentThread]);
NSOperationQueue *mainQuene = [NSOperationQueue mainQueue];
for (int i = 0; i < 10; i++) {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"主線程-----%@-------%d",[NSThread currentThread],i);
}];
[mainQuene addOperation:blockOperation];
}
}
GCD 多線程優(yōu)化 這個(gè)下一篇再說(shuō)吧