你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> IOS-線程操作之NSThread/NSOperation/GCD

IOS-線程操作之NSThread/NSOperation/GCD

編輯:IOS開發綜合

1NSThread.聲明線程,啟動線程:(第一個參數聲明了目標類,第2個參數聲明了目標方法,第3個參數為該方法的參數)

NSThread *thread=[[NSThread alloc] initWithTarget:selfselector:@selector(saleTicketMethod:) object:@"線程--1"];
[thread start];

2.IOS跟Android一樣都是線程不安全的 也就是所有UI更新都必須在主線程內完成,這樣,當我們在另一條線程中想要修改View,如下:

(第一個參數為目標方法,第2個參數為該方法的參數 ,並且只能是1個 。)

[self performSelectorOnMainThread:@selector(updateView:) withObject:str waitUntilDone:YES];

3.當不同的線程搶奪共同的資源時,需要對線程加鎖,以下為一個賣票的系統例子:

#import "CSZViewController.h"

@interface CSZViewController ()
{
    int _ticketNum;
    NSLock *_lock;
}
@end

@implementation CSZViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void) updateView:(NSString *) text
{
    NSString *str=[NSString stringWithFormat:@"%@ \n%@",self.textView.text,text];
    self.textView.text=str;
}

- (void)saleTicketMethod:(NSString *)threadName
{
    while (true) {
        
        if (_ticketNum>0) {
            [_lock lock];
            NSString *str=[NSString stringWithFormat:@"%@線程的票數為:%d",threadName,_ticketNum];
            [self performSelectorOnMainThread:@selector(updateView:) withObject:str waitUntilDone:YES];
            
            _ticketNum--;
            [_lock unlock];
            if ([threadName isEqualToString:@"線程--1"]) {
                [NSThread sleepForTimeInterval:1.0];
            }else{
                [NSThread sleepForTimeInterval:2.0];
            }
            
            
        }else
        {
            NSString *str=[NSString stringWithFormat:@"售票結束!%@",threadName];
            [self performSelectorOnMainThread:@selector(updateView:) withObject:str waitUntilDone:YES];
            break;
        }
        
    }
}

- (IBAction)threadClick:(id)sender {
    
    _ticketNum=20;
    //計算剩余票數
    //如果有票,則賣出
    //沒有則停止;
    _lock=[[NSLock alloc] init];
    
    NSThread *thread=[[NSThread alloc] initWithTarget:self selector:@selector(saleTicketMethod:) object:@"線程--1"];
    NSThread *thread1=[[NSThread alloc] initWithTarget:self selector:@selector(saleTicketMethod:) object:@"線程--2"];
    [thread start];
    [thread1 start];
}



@end


---NSOperation的使用是蘋果為我們實現多線程通過的一套簡潔的API。它為我們避免搶奪同個資源做了屏蔽。同時定義了線程隊列的概念,開發人員不用考慮這方面的東西。

其用法主要分為3點:

1,定義線程隊列 (設置同時運行的線程數,因為開線程也是需要消費資源的,類比JAVA的線程池)

NSOperationQueue *queue=[[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:5];


2.定義異步線程 。(同樣,以下參數也是聲明了線程方法所在的類以及所需要的方法參數)

NSInvocationOperation *opera=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operaSaleMethod:) object:@"線程操作1"];
NSInvocationOperation *opera2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operaSaleMethod:) object:@"線程操作2"];

3.將隊列放進線程中。線程任務就會通過隊列自動分配。

[queue addOperation:opera];
[queue addOperation:opera2];

4.對於操作的方法,使用同一資源,不需要做加鎖的處理

-(void) operaSaleMethod:(NSString *)threadName
{
    while (true) {
        if (_ticketNum>0) {
            
            if ([threadName isEqualToString:@"線程操作1"]) {
                [NSThread sleepForTimeInterval:2.0];
            }else{
                [NSThread sleepForTimeInterval:1.2];
            }
            
            NSString *str=[NSString stringWithFormat:@"%@線程的票數為:%d",threadName,_ticketNum];
            
            [self performSelectorOnMainThread:@selector(updateView:) withObject:str waitUntilDone:YES];
            _ticketNum--;
        }else
        {
            NSString *str=[NSString stringWithFormat:@"%@售票結束!",threadName];
            [self performSelectorOnMainThread:@selector(updateView:) withObject:str waitUntilDone:YES];
            break;
        }
    }
    
}

GCD是用C語言寫的支持多線程開發的一套 API,它的模式跟Operation差不多,並在此基礎上增加了組的概念,在所有組完成後提供一套觸發通知的機制。

1.定義隊列

//#define DISPATCH_QUEUE_PRIORITY_HIGH        2
    //#define DISPATCH_QUEUE_PRIORITY_DEFAULT     0
    //#define DISPATCH_QUEUE_PRIORITY_LOW         (-2)
    //#define DISPATCH_QUEUE_PRIORITY_BACKGROUND  INT16_MIN
    dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

2.定義組

dispatch_group_t group=dispatch_group_create();

3.定義異步任務並添加到隊列中

dispatch_group_async(group, queue, ^{
        [self gcdSaleMethod:@"線程操作1"];
    });
    dispatch_group_async(group, queue, ^{
        [self gcdSaleMethod:@"線程操作2"];
    });

4.隊列獲取通知

dispatch_group_notify(group, queue, ^{
        NSLog(@"線程操作完成");
    });

從日志可以看出 只有所有線程跑完了 才會回調該block中的內容

2014-08-11 15:08:38.982 ThreadSample01[5256:4007] 線程操作2售票結束!
2014-08-11 15:08:39.037 ThreadSample01[5256:1903] 線程操作1售票結束!
2014-08-11 15:08:39.042 ThreadSample01[5256:4007] 線程操作完成



  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved