OC之多线程

本文主要介绍了Objective-C(OC)中的多线程技术,包括NSThread的基础使用,重点探讨了GCD(Grand Central Dispatch)如何充分利用多核优势,详细讲解了并发队列与串行队列的获取及同步、异步执行方法。此外,还提到了线程间通信的重要性和NSOperation的两种实现方式,如NSInvocationOperation和NSBlockOperation,并强调可以通过重写main方法来定制NSOperation的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事情太忙碌,直接用OC记录了,以后使用时,再换成Swift

多线程

1、NSThread

-》最基本的创建方式

    /**
     创建线程第一种方法,需要调用start方法才可以执行
     */
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    thread.name = @"Custom Thread";
    [thread start];

-》直接创建,无须手动启动

    /**
     *  创建线程后自动启动
     */
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

    /**
     *  隐式创建并启动线程
     */
    [self performSelectorInBackground:@selector(run) withObject:nil];

-》其他方法

    /**
     *  获得当前线程
     */
    NSThread *thread = [NSThread currentThread];
    /**
     *  获得主线程
     */
    NSThread *mainThread = [NSThread mainThread];
-》线程间的通信
    /**
     *  线程间的通信
     */
    [thread performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:true];


2、GCD(重点,充分利用手机的多核)

-》队列

--》并发队列:dispatch_get_global_queue

--》串行队列:dispatch_queue_create、dispatch_get_main_queue

-》执行方法

--》同步:dispatch_sync

--》异步:dispatch_async

-》线程间的通信

/**
 *  使用GDC实现线程之间数据传递
 */
- (void)asyncDownloadImage {
    // 1、创建并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 2、添加任务到队列中
    dispatch_async(queue, ^{
        NSString *value = @"人生若只如初见";
        // 3、将数据传递给主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            self.textView.text = value;
        });
    });
}

-》其他方法

/**
 *  GCD中代码只执行一次
 */
- (void)once {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"这里只能执行一次,多了我不会执行的!");
    });
}

/**
 *  GCD中的延迟操作
 */
- (void)delay {
    NSLog(@"开始执行,%@", [NSThread currentThread]);
    // 延迟操作
    // 延迟时间
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
    // 全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_after(when, queue, ^{
        NSLog(@"终于执行到这里了,%@", [NSThread currentThread]);
    });
}

/**
 *  GCD队列组实现下载
 */
- (void)groupDownloadImage {
    // 创建队列组
    dispatch_group_t group = dispatch_group_create();
    // 队列组中执行异步操作
    __block UIImage *imageLeft = nil;
    dispatch_group_async(group, GlobalQueue, ^{
        imageLeft = [self imageWithURL:@"http://img1.touxiang.cn/uploads/20121023/23-012600_360.jpg"];
    });
    // 队列组中执行异步操作
    __block UIImage *imageRight = nil;
    dispatch_group_async(group, GlobalQueue, ^{
        imageRight = [self imageWithURL:@"http://img1.touxiang.cn/uploads/20121023/23-012609_92.jpg"];
    });
    // 队列组异步执行结束通知
    dispatch_group_notify(group, MainQueue, ^{
        NSLog(@"%@", imageLeft);
    });
    
}


3、NSOperation

-》NSInvocationOperation

/**
 *  通过NSInvocationOperation实现多线程
 */
- (void)invocationOperation {
    // 1、创建NSInvocationOperation对象
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"NSInvocationOperation"];
    // 2、启动Operation
    [operation start];
}


-》NSBlockOperation

/**
 *  通过NSBlockOperation实现多线程
 */
- (void)blockOperation {
    // 创建NSBlockOperation对象
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSThread *thread = [NSThread currentThread];
        NSLog(@"通过NSBlockOperation实现多线程, %@", thread);
    }];
    // 在NSBlockOperation对象中封装多个执行操作
    // 当存在多个执行操作的时候,会开启多线程,但不是因为调用addExecutionBlock方法而开启多线程的
    // NSBlockOperation *operation = [[NSBlockOperation alloc] init];
    [operation addExecutionBlock:^{
        NSThread *thread = [NSThread currentThread];
        NSLog(@"通过NSBlockOperation实现多线程, %@", thread);
    }];
    [operation addExecutionBlock:^{
        NSThread *thread = [NSThread currentThread];
        NSLog(@"通过NSBlockOperation实现多线程, %@", thread);
    }];
    // 启动操作
    [operation start];
    // 取消线程操作
    // [operation cancel];
}

-》NSOperationQueue

/**
 *  通过NSOperationQueue队列实现多线程
 */
- (void)operationQueue {
    // 1、创建NSOperationQueue对象
    // 获得新线程队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 获得主线程队列
    // NSOperationQueue *queue = [NSOperationQueue mainQueue];
    // 获得当前线程队列
    // NSOperationQueue *queue = [NSOperationQueue currentQueue];
    // 2、创建NSInvocationOperation对象
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"NSInvocationOperation"];
    NSInvocationOperation *runOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"NSInvocationOperationRun"];
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSThread *thread = [NSThread currentThread];
        NSLog(@"NSBlockOperation实现多线程, %@", thread);
    }];
    // 设置最大并发数
    // queue.maxConcurrentOperationCount = 1;
    // 取消队列操作
    // [queue cancelAllOperations];
    // 暂停队列与恢复队列应用在UITableView中,滚动事件时,暂停网络请求,以便提高UI性能
    // 暂停队列
    // queue.suspended = YES;
    // 恢复队列
    // queue.suspended = NO;
    // 设置操作依赖,指定执行顺序:表示blockOperation依赖runOperation,blockOperation在runOperation执行后再执行
    [blockOperation addDependency:runOperation];
    
    // 3、将操作添加到队列中,自动执行
    [queue addOperation:operation];
    [queue addOperation:runOperation];
    [queue addOperation:blockOperation];
}

/**
 *  Operation操作结束监听
 */
- (void)operationListener {
    // 创建NSBlockOperation对象
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"NSBlockOperation实现操作监听, %@", [NSThread currentThread]);
    }];
    operation.completionBlock = ^{
        NSLog(@"这里难道是线程结束后的回调函数?谁知道呢! %@", [NSThread currentThread]);
    };
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:operation];
}

-》自定义NSOperation

重写main方法,实现自定义NSOperation功能

/**
 *  自定义Operation
 *  将所需要的操作写在main方法中
 */
- (void)main {
    // 需要自己创建自动释放池。Operation如果是异步操作,将无法访问主线程的自动释放池
    @autoreleasepool {
        // 检测Operation是否被取消,对取消操作做出响应
        if (self.isCancelled) {
            return;
        }
        NSURL *url = [NSURL URLWithString:self.uri];
        NSData *data = [NSData dataWithContentsOfURL:url];
        if (self.isCancelled) {
            return;
        }
        UIImage *image = [UIImage imageWithData: data];
        if (self.isCancelled) {
            return;
        }
        if ([self.delegate respondsToSelector:@selector(downloadOperation:didFinishDownload:)]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate downloadOperation:self didFinishDownload:image];
            });
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值