ios多线程基于NSOperation实现

ios多线程方案由以下几种,目前官方推荐使用NSOperation,和java一样有线程池ThreadPool的概念,ios线程池就是NSOperationQueue。

NSOperation使用步骤如下:

下面给出demo,NSOperation是个抽象类,NSInvocationOperation 和NSBlockOperation是它的子类,demo会介绍这种子类的用法以及配合NSOperationQueue一起使用实现多线程。同时介绍线程的启动,暂停,继续,取消。

//
//  ThreadViewController.m
//  study2024
//
//  Created by zhifei  zhu on 2024/8/17.
//

#import "ThreadViewController.h"

@interface ThreadViewController ()
- (IBAction)mainQueue:(id)sender;
@property (weak, nonatomic) IBOutlet UIButton *mainQueueBtn;

- (IBAction)NSInvocationOperationTest:(id)sender;
- (IBAction)NSBlockOperationTest:(id)sender;
- (IBAction)NSOperationQueueStart:(id)sender;
- (IBAction)NSOperationQueuePause:(id)sender;
- (IBAction)NSOperationQueueContinue:(id)sender;
- (IBAction)NSOperationQueueConcel:(id)sender;
@property NSOperationQueue *queue;
@end

@implementation ThreadViewController
//懒加载queue属性
-(NSOperationQueue *)queue{
    if(_queue==nil){
        _queue=[[NSOperationQueue alloc]init];
        _queue.maxConcurrentOperationCount=5;//设置队列最大并发数,不是线程总数,一般用2n+1 n代表cpu核数
        
    }
    return _queue;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/
//1.测试NSInvocationOperation继承至NSOperation
- (IBAction)NSInvocationOperationTest:(id)sender {
    NSInvocationOperation *nsInvocationOperation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationTest) object:nil];
    [nsInvocationOperation setCompletionBlock:^{
        NSLog(@"hello  nsInvocationOperation is completion %@",[NSThread currentThread]);
    }];
    //直接start不会新建线程,还是运行在main主线程
//    [nsInvocationOperation start];
    //加入队列,会新起线程
    NSOperationQueue *nsOperationQueue=[[NSOperationQueue alloc]init];
    [nsOperationQueue addOperation:nsInvocationOperation];
}
- (void) operationTest{
    NSLog(@"hello NSInvocationOperationTest %@",[NSThread currentThread]);
}

//2.测试NSBlockOperation继承至NSOperation
- (IBAction)NSBlockOperationTest:(id)sender {
    NSBlockOperation *nsBlockOperation=[NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"hello  NSBlockOperation %@",[NSThread currentThread]);
    }];
    [nsBlockOperation setCompletionBlock:^{
        NSLog(@"hello  NSBlockOperation is completion %@",[NSThread currentThread]);
    }];
    //直接start不会新建线程,还是运行在main主线程
//    [nsBlockOperation start];
    //加入队列,会新起线程
    NSOperationQueue *nsOperationQueue=[[NSOperationQueue alloc]init];
    [nsOperationQueue addOperation:nsBlockOperation];
}


//3.测试主队列,回到主队列就可以做线程间数据通信了
- (IBAction)mainQueue:(id)sender {
    //添加NSBlockOperation到当前queue
    [self.queue addOperationWithBlock:^{
        NSLog(@"下载完成,当前队列%@",[NSOperationQueue currentQueue]);
    }];
    //获取主队列
    [ [NSOperationQueue mainQueue]addOperationWithBlock:^{
        
        NSLog(@"回到主队列,主线程,这里可以更新UI,当前队列%@,当前线程%@",[NSOperationQueue currentQueue],[NSThread mainThread]);
        //更新按钮文字颜色为红色
        [self.mainQueueBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
    }];
}


//4.测试线程队列所有线程开始执行
- (IBAction)NSOperationQueueStart:(id)sender {
    
    for(int a=0;a<20;a++){
        [self.queue addOperationWithBlock:^{
            //_queue.maxConcurrentOperationCount=2;//设置队列最大并发数,不是线程总数 不设置并发数,会每次都新创建一个
            [NSThread sleepForTimeInterval:3];//睡眠3秒
            NSLog(@"%d线程执行完成,当前线程%@",a,[NSThread currentThread]);
        }];
    }
  
    
}
//5.测试线程队列所有线程暂停
- (IBAction)NSOperationQueuePause:(id)sender {
    [self.queue setSuspended:YES];
    NSLog(@"暂停,当前线程数%lu",self.queue.operationCount);
}
//6.测试线程队列所有线程继续执行
- (IBAction)NSOperationQueueContinue:(id)sender {
    [self.queue setSuspended:NO];
    NSLog(@"继续,当前线程数%lu",self.queue.operationCount);

}
//7.测试线程队列所有线程取消
- (IBAction)NSOperationQueueConcel:(id)sender {
    [self.queue cancelAllOperations];
    NSLog(@"取消所有线程,当前线程数%lu",self.queue.operationCount);

}


@end

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值