首页 > 代码库 > IOS-线程操作之NSThread/NSOperation

IOS-线程操作之NSThread/NSOperation

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;
        }
    }
    
}