欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程编程(NSThread、NSOperation、GCD)

程序员文章站 2024-03-24 13:08:10
...

多线程编程(NSThread、NSOperation、GCD)

基本概念

  • 进程:可以理解为一个运行中的应用程序
  • 线程:程序执行流的最小单元,线程是进程的一个实体
  • 同步:只能在当前线程按先后顺序执行,不开启新线程
  • 异步:可以在当前线程开启多个新线程,可不按顺序执行
  • 队列:装在线程任务的队形结构
  • 并发:线程执行可以同时一起执行
  • 串行:线程执行只能逐一有先后顺序的执行
  • -

多线程对比

  • NSThread : 每个NSThread对象对应一个线程,真正最原始的线程
    • 优点:NSThread 轻量级最低,相对简单
    • 缺点:手动管理所有的线程活动,如生命周期、线程同步、睡眠等
  • NSOperation 自带线程管理的抽象类
    • 优点:自带线程周期管理,操作上可更注重自己逻辑
    • 缺点:面向对象的抽象类,只能实现它或者使用它定义好的两个子类NSInvocationOperation 和 NSBlockOperation
  • GCD:Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法
    • 优点:最高效,避开并发陷阱。
    • 缺点:基于C实现
    • -

选择小结

  1. 简单而安全的选择 NSOperation 实现多线程
  2. 处理大量并发数据,又追求性能效率的选择GCD
  3. NSThread 处于最底层,可塑性很强。当然也可以基于此造个*

场景选择

使用方法

1.NSThread


//动态创建线程
- (void)dynamicCreateThread {
    NSThread *thread = [[ NSThread alloc] initWithTarget:self
                                                selector:@selector(loadImageSource:)
                                                  object:imgUrl];
    // 设置线程的优先级(0.0 - 1.0,1.0*)
    thread.threadPriority = 1;
    [thread start];
}

//静态创建线程
- (void)staticCreateThread {
    [NSThread detachNewThreadSelector: @selector (loadImageSource:)
                             toTarget: self
                           withObject:imgUrl];
}

//隐式创建线程
- (void)implicitCreateThread {
    [self performSelectorInBackground: @selector (loadImageSource:)
                           withObject:imgUrl];
}

- (void)loadImageSource:(NSString*)url {

    NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
    UIImage *image = [UIImage imageWithData:imgData];
    if (imgData!= nil) {
        [self performSelectorOnMainThread: @selector (refreshImageView:)
                               withObject:image
                            waitUntilDone: YES];
    } else {
        NSLog(@"there no image data" );
    }
}

-(void)refreshImageView:(UIImage*)image {
    [imageView setImage:image];
}

NSThread 拓展

    // 获取当前线程
    NSThread *current = [NSThread currentThread];
    // 主线程
    NSThread *main = [NSThread mainThread];
    // 睡眠当前线程
    [NSThread sleepForTimeInterval:2];


    //在指定线程上执行操作
    [self performSelector:@selector(run) onThread:current withObject:nil waitUntilDone:YES];
    //在主线程上执行操作
    [self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];
    //在当前线程执行操作
    [self performSelector:@selector(run) withObject:nil];

2.NSOperation

主要的实现方式:结合NSOperation和NSOperationQueue实现多线程编程

  • 实例化NSOperation的子类,绑定执行的操作。
  • 创建NSOperationQueue队列,将NSOperation实例添加进来。
  • 系统会自动将NSOperationQueue队列中检测取出和执行NSOperation的操作。
//使用子类NSInvocationOperation
- (void)useInvocationOperation {
    NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                                      selector:@selector(loadImageSource:)
                                                                                        object:imgUrl];
    //[invocationOperation start];//直接会在当前线程主线程执行
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:invocationOperation];
}

//使用子类NSBlockOperation
- (void)useBlockOperation {
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^ {
        [self loadImageSource:imgUrl];
    }];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:blockOperation];
}
//使用继承NSOperation
- (void)useSubclassOperation {
    LoadImageOperation *imageOperation = [LoadImageOperation new];
    imageOperation.loadDelegate = self;
    imageOperation.imgUrl = imgUrl;
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:imageOperation];
}

- (void)loadImageSource:(NSString*)url {
    NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
    UIImage *image = [UIImage imageWithData:imgData];
    if (imgData!= nil) {
        [self performSelectorOnMainThread: @selector(refreshImageView1:)
                               withObject:image waitUntilDone: YES];
    } else {
        NSLog (@"there no image data");
    }
}

3.GCD

相关标签: 多线程 ios