iOS-進階整理07 - 多線程NSThread NSOperation

多線程

程序:由源代碼生成的可執行應用。
進程:一個正在運行的程序可用看做一個進程,進程擁有獨立運行所需要的全部資源。
線程:程序中獨立運行的代碼段
iOS5之后子線程也有刷新UI的能力,但不夠快
iOS中關于UI的添加和刷新必須在主線程中操作

使用多線程開發的優點:

資源利用率更好,程序設計在某些情況下更簡單,程序響應更快

缺點:

盡管提升了性能,但是存在一些訪問限制,比如線程同步、線程互斥等,多線程在使用的時候,最終是要回到主線程刷新UI,如果開辟過多的多線程,會造成CPU的消耗

一、NSThread

每個線程都維護著自己對應的NSAutoreleasePool對象,將其放在線程棧的棧頂。當線程結束時會情況自動釋放池
在應用程序打開的是,系統會自動為主線程創建一個自動釋放池
我們收到創建的子線程需要我們手動添加自動釋放池


    //1.輕量級別的多線程實現方式  
    //當使用alloc init方式,需要我們手動啟動,如果使用便利構造器的方法,不需要手動啟動  
    //object 是線程回調方法的參數,不需要就寫nil  
    NSThread *forThread = [[NSThread alloc]initWithTarget:self selector:@selector(aHundredMillion) object:nil];  
  
    //通過便利構造器的方法創建Thread對象,不用手動啟動  
    [NSThread detachNewThreadSelector:@selector(thread_1Action:) toTarget:self withObject:@"thread_1"];  
  
    //為forThread命名      
    forThread.name = @"老二";  
      
    //線程優先級,當優先級越高,線程被先執行的概率越高,0~1.0越來越高  
    forThread.threadPriority = 1.0;  
      
    //啟動線程  
    [forThread start];  
      
    //得到當前線程的信息  
    NSLog(@"iamgeThread--%@",[NSThread currentThread]);  
     //得到主線程的信息  
    NSLog(@"%@",[NSThread mainThread]);  
  
    //線程休眠  
    [NSThread sleepForTimeInterval:2];  

//結束線程
//1.給線程發結束消息[forThread cancel];
//2.理解結束線程[NSThread exit];
//判斷線程是否在執行[forThread isExecuting];
//判斷線程是否執行完畢[forThread isFinished];

NSObject的多線程方法

//1.從主線程進入子線程  
 [self performSelectorInBackground:@selector(objectThreadAction:) withObject:@"object開的子線程"];  
//NSObject進入子線程  
-(void)objectThreadAction:(NSString*)sender  
{  
    NSLog(@"%@",sender);  
    NSLog(@"%@",[NSThread currentThread]);  
    //從子線程回到主線程  
    //waitUnitDone:YES只有回主線程的回調方法執行結束才會執行下面的操作。NO:與之相反  
    [self performSelectorOnMainThread:@selector(backMainThread) withObject:nil waitUntilDone:YES];  
    NSLog(@"在回到主線程的底下");  
}  

線程鎖

@property (nonatomic,retain)NSLock *myLock;//線程鎖,當多個線程同時訪問同一資源的時候,對資源進行保護  
@property (nonatomic,assign)int ticket_Sum;//線程直接跳的總數  
  
@end  
  
@implementation ViewController  
  
-(NSLock *)myLock  
{  
    if (!_myLock) {  
        _myLock = [[NSLock alloc]init];  
    }  
    return _myLock;  
}  
  
//線程鎖學習  
-(void)lock_study  
{  
    @synchronized(self) {  
        //線程鎖,保證當前只有一個線程在訪問該資源  
        //將需要加鎖保護的代碼寫在花括號內  
    }  
      
    //當線程訪問的是,加線程鎖  
    [self.myLock lock];  
      
    while (true) {  
        if (_ticket_Sum > 0)  
        {  
            _ticket_Sum--;  
            NSLog(@"剩余票===  %d",_ticket_Sum);  
        }  
        else  
        {  
            break;  
        }  
    }        
    //當正在執行的線程執行完操作的時候,解鎖。其他線程可以訪問  
    [self.myLock unlock];    
}  

二、NSOperation

NSOperation類,在MVC中屬于M,是用來封裝單個任務的相關代碼和數據的抽象類。
因為它是抽象的,不能直接使用這個類,而使用子類(NSInvocationOperation或NSBlockOperation)來執行任務。
NsOperation,只是一個操作,本身無主線程子線程之分,可以在任意線程中使用,通常與NSOperationQueue結合使用

-(void)operation  
{  
    //初始化一個任務 target-action  
    NSInvocationOperation *invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction:) object:@"參數"];  
      
    //當任務不在隊列中,需要手動啟動  
    [invocation start];  
         
    //操作block的方法  
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{  
        //實現我們需要做的操作  
        NSLog(@"block  當前線程---%@",[NSThread currentThread]);  
    }];  
      
    //為block操作添加多個block執行  
    //當使用addExecutionBlock添加可執行的block時,這些block會在當前線程或者其他子線程中進行  
    for (int i = 0; i < 10; i++) {  
          
        [blockOperation addExecutionBlock:^{  
            NSLog(@"block2 當前線程-- %@",[NSThread currentThread]);  
        }];  
    }        
    //最后執行的block,此block會在最后執行  
    blockOperation.completionBlock = ^()  
    {  
        NSLog(@"最后執行的block-------%@",[NSThread currentThread]);  
    };  
      
    //all block must be before  start  
    //啟動操作  
    [blockOperation start];  
    NSLog(@"我在最下面");  
}  

把任務加入隊列當中

//隊列quene  NSOperationQuene是對GCD的OC級別的封裝  
-(void)operationQuene  
{  
    //先初始化隊列的對象,(其他隊列:出了主隊列,人為初始化的隊列都是其他隊列)  
    NSOperationQueue *otherQuene = [[NSOperationQueue alloc]init];  
      
    //設置最大并發數,默認為-1,可以無限個,設置為1的時候,在同一時刻只能執行一個操作  
    otherQuene.maxConcurrentOperationCount = 10;  
      
    for (int i = 0; i < 10; i++) {  
        //創建可執行的操作對象  
        NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{  
            NSLog(@"隊列-----當前線程---%@--%d",[NSThread currentThread],i);  
        }];            
        if (i == 3) {  
              
        }  
        //將block操作添加到隊列中,當操作對象添加到隊列中之后,就不需要手動啟動了  
        [otherQuene addOperation:blockOperation];  
    }  
    
    NSBlockOperation *blockOperation_0 = [NSBlockOperation blockOperationWithBlock:^{  
        NSLog(@"隊列-----當前線程---%@--%d",[NSThread currentThread],0);  
    }];  
    NSBlockOperation *blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{  
        NSLog(@"隊列-----當前線程---%@--%d",[NSThread currentThread],1);  
    }];  
    NSBlockOperation *blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{  
        NSLog(@"隊列-----當前線程---%@--%d",[NSThread currentThread],2);  
    }];  
    NSBlockOperation *blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{  
        NSLog(@"隊列-----當前線程---%@--%d",[NSThread currentThread],3);  
    }];  
    NSBlockOperation *blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{  
        NSLog(@"隊列-----當前線程---%@--%d",[NSThread currentThread],4);  
    }];  
      
    //為事件添加依賴關系,第四個必須在第三個后面執行,這樣第四個任務一定在第三個執行后,才會執行  
    //要先添加依賴再講事件添加到隊列  
    [blockOperation_4 addDependency:blockOperation_3];  
      
    //添加進隊列  
    [otherQuene addOperation:blockOperation_0];  
    [otherQuene addOperation:blockOperation_1];  
    [otherQuene addOperation:blockOperation_2];  
    [otherQuene addOperation:blockOperation_3];  
    [otherQuene addOperation:blockOperation_4];  
}  

添加到主隊列

//主隊列  
-(void)operationMainQuene  
{  
      
    NSLog(@"當前線程--與主隊列無關--%@",[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 多線程優化 這個下一篇再說吧

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Object C中創建線程的方法是什么?如果在主線程中執行代碼,方法是什么?如果想延時執行代碼、方法又是什么? 1...
    AlanGe閱讀 1,792評論 0 17
  • 單例模式例子: https://github.com/XiaoRuiZuo/Singleton 多線程:多線程是為...
    Lee堅武閱讀 1,421評論 0 50
  • .一.進程 進程:是指在系統中正在運行的一個應用程序,每個進程之間是獨立的,每個進程均運行在其專用且受保護的內存空...
    IIronMan閱讀 4,521評論 1 33
  • 一、基本概念 線程是用來執行任務的,線程徹底執行完任務A才能執行任務B,為了同時執行兩個任務,產生了多線程 1、進...
    空白Null閱讀 727評論 0 3
  • 一頓熱鬧的年夜飯。 年前新安的路燈照的地面很亮,轎車疾馳而過,兩旁的人家都是燈火通明,時有屋子外面掛上大紅燈籠。我...
    筵敷閱讀 448評論 0 0