iOS-進(jìn)階整理07 - 多線程N(yùn)SThread NSOperation

多線程

程序:由源代碼生成的可執(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ō)吧

最后編輯于
?著作權(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)容

  • Object C中創(chuàng)建線程的方法是什么?如果在主線程中執(zhí)行代碼,方法是什么?如果想延時(shí)執(zhí)行代碼、方法又是什么? 1...
    AlanGe閱讀 1,916評(píng)論 0 17
  • 單例模式例子: https://github.com/XiaoRuiZuo/Singleton 多線程:多線程是為...
    Lee堅(jiān)武閱讀 1,465評(píng)論 0 50
  • .一.進(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,603評(píng)論 1 33
  • 一、基本概念 線程是用來(lái)執(zhí)行任務(wù)的,線程徹底執(zhí)行完任務(wù)A才能執(zhí)行任務(wù)B,為了同時(shí)執(zhí)行兩個(gè)任務(wù),產(chǎn)生了多線程 1、進(jìn)...
    空白Null閱讀 803評(píng)論 0 3
  • 一頓熱鬧的年夜飯。 年前新安的路燈照的地面很亮,轎車疾馳而過(guò),兩旁的人家都是燈火通明,時(shí)有屋子外面掛上大紅燈籠。我...
    筵敷閱讀 462評(píng)論 0 0

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