iOS多線程編程之基礎

多線程是爲了解決主線程被阻塞,並提升效率的一種方式.
編程

首先咱們要學習多線程編程就要看看它有哪幾種方式:多線程

  1. NSThread併發

  2. NSOperationapp

  3. Grand Centeral Dispatch
    異步

咱們看看NSThread的建立方式::async

    

NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(btnSum:) object:nil];
    //經過iniit 建立NSThread 須要手動開啓線程
    [thread start];
    [thread cancel];
    //第二種開啓並自動執行 btnSum 是本身寫的一個方法
    [NSThread detachNewThreadSelector:@selector(btnSum:) toTarget:self withObject:nil];
- (void)btnSum:(UIButton *)sender {
    
    long sum = 0;
    
    for (long i = 0; i < 10; i ++) {
        sum += i;
        NSLog(@"number %ld current Thred : %@  %@",sum,[NSThread currentThread],[NSOperationQueue currentQueue]);
        
    }
    
}

 使用NSThread 或直接從 NSObject 的類方法 performSelectorInBackground:withObject: 來建立一個線程。若是你選擇thread來實現多線程,那麼 NSThread 就是官方推薦優先選用的方式函數


NSOperation學習

/**
     NSOperationQueue線程隊列
*/
//    1.NSInvocationOperation操做

    NSInvocationOperation *iOP =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(btnSum:) object:nil];
    
    //Operation是不能執行的,須要隊列進行調用
    [[NSOperationQueue mainQueue] addOperation:iOP];
    
    //2.NSBlockOperation
    
    NSBlockOperation *bOP = [[NSBlockOperation alloc]init];
   //以代碼塊的方式添加操做
    [bOP addExecutionBlock:^{
        [self btnSum:nil];
    }];
    
    //添加到線程隊列
    [self.operationQueue addOperation:bOP];

爲了建立一個簡單的NSOperation對象,直接重寫了getter方法
ui

- (NSOperationQueue *)operationQueue{
    if (!_operationQueue ) {
        _operationQueue = [[NSOperationQueue alloc]init];
        [_operationQueue setName:@"queue"];
    }
    return _operationQueue;
}
//NSBlockOperation 建立方式,能夠用便利構造器,直接添加block
    NSBlockOperation *bOP = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 100; i ++) {
            NSLog(@"%d,當前線程:::%@",i,[NSThread currentThread]);
        }
    }];
    NSBlockOperation *aOP = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 100; i ++) {
            NSLog(@"%d,當前線程:::%@",i,[NSThread currentThread]);
        }
    }];
    NSBlockOperation *cOP = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 100; i ++) {
            NSLog(@"%d,當前線程333333333:::%@",i,[NSThread currentThread]);
        }
    }];
    //添加到主隊列
    [[NSOperationQueue mainQueue] addOperation:bOP];
    [[NSOperationQueue mainQueue] addOperation:cOP];
//自定義隊列
    self.operation = [[NSOperationQueue alloc]init];
    //設置最大併發數
    self.operation.maxConcurrentOperationCount = 1;//在同一連續時刻只執行一個操做
//    self.operation.maxConcurrentOperationCount = 4;
    
   [self performSelectorInBackground:@selector(printNumber:) withObject:@"NSObject"];
  
    [self.operation addOperation:aOP];
    [self.operation addOperation:cOP];

GCDspa

/**
GCD 中央派發機制 Grand Central Dispatch
 基於函數,使用分發隊列FIFO
*/
    //1.主線程隊列::等同於[NSOperationQueue mainQueue]
    //2.全局線程隊列 後臺隊列  並行
    //3.自定義線程隊列 DISPATCH_QUEUE_SERIAL 串行
//                   DISPATCH_QUEUE_CONCURRENT 並行
    /*
    //建立自定義隊列,默認爲串行(故加了個優先級的東東::DISPATCH_QUEUE_PRIORITY_DEFAULT)
    dispatch_queue_t myQueue = dispatch_queue_create("com.liulei.www.myQueue",DISPATCH_QUEUE_PRIORITY_DEFAULT);
    
//串行隊列

    // dispatch_async(隊列, 執行block) 異步
    // dispatch_sync(隊列, 執行block)同步
    dispatch_async(myQueue, ^{
        [self printNumber:@"GCD"];
        [self printNumber:@"GCD1"];
    });
    
    
    dispatch_async(myQueue, ^{
        [self printNumber:@"GCD2"];
    });
    */
    /*
//並行隊列
    dispatch_queue_t conQueue = dispatch_queue_create("conQueue", DISPATCH_QUEUE_CONCURRENT);
    
    //一個bolck中串行
    dispatch_async(conQueue, ^{
        //順序執行
        [self printNumber:@"G1"];
        [self printNumber:@"G2"];
        [self printNumber:@"G3"];
    });
    //並行執行
    dispatch_async(conQueue, ^{
        
        [self printNumber:@"G4"];
    });
    
    dispatch_async(conQueue, ^{
        [self printNumber:@"G5"];
    });
    */
    //dispatch_after ..//延時操做

既然說道多線程的開發,不免會在多線程之間進行通信;
利用NSObject的一些類方法,能夠輕鬆搞定。(NSObject內置方法來建立線程)

在應用程序主線程中作事情:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array

在指定線程中作事情:
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array
在當前線程中作事情:
//Invokes a method of the receiver on the current thread using the default mode after a delay.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

performSelector:withObject:afterDelay:inModes:

取消發送給當前線程的某個消息
cancelPreviousPerformRequestsWithTarget:

cancelPreviousPerformRequestsWithTarget:selector:object:

如在咱們在某個線程中下載數據,下載完成以後要通知主線程中更新界面等等,能夠使用以下接口:- [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];好比下載完成後,通知主線程(ui線程),以便app再作其餘工做

相關文章
相關標籤/搜索