IOS多线程

落爺英雄遲暮 提交于 2020-12-15 01:43:07

我们这里不讲解pthread,这个是posix的标准,完全用c语言实现,想要了解的直接上网搜索 posix pthread。
我们现在用的主要有三种:NSThread,GCD, NSOperation.用得最多的是GCD, NSOperation是对GCD的面向对象封装。

NSThread

NSThread是最像java线程api的一种,使用的NSThread的坏处是我们要自己管理线程的生命周期。

API:


/**
 * 创建线程的方式3
 */
- (void)createThread3
{
    // 这2个不会创建线程,在当前线程中执行
//    [self performSelector:@selector(download:) withObject:@"http://c.gif"];
//    [self download:@"http://c.gif"];
    
    [self performSelectorInBackground:@selector(download:) withObject:@"http://c.gif"];
}

/**
 * 创建线程的方式2
 */
- (void)createThread2
{
    [NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"http://a.jpg"];
}

/**
 * 创建线程的方式1
 */
- (void)createThread1
{
    // 创建线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:@"http://b.png"];
    thread.name = @"下载线程";
    
    // 启动线程(调用self的download方法)
    [thread start];
}

线程锁使用关键字@synchronized

#GCD 这也是c语言的api,但是这个api是针对执行队列的,我们需要创建执行队列,而不是线程。

API

队列

获取队列

获取主队列,也就是只有主线程执行的队列。

dispatch_queue_t queue = dispatch_get_main_queue();

获取全局队列,非主线程存在的一些队列,队列里面的线程数由系统控制。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

第一个参数为这个队列的优先级,第二个为保留参数,添加到这个队列里的所有任务都会并行执行。

创建队列

dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);

第一个参数是为这个队列指定一个标签,第二个为这个队列的属性。添加到这个队列里的所有任务都会串行执行,一般这个队列里只有一个线程。

执行任务

一共四个API

同步执行

dispatch_sync(queue, ^{})

当前线程会等待队列里的线程回调执行完block里面的代码后再往下执行。

异步执行

dispatch_async(queue, ^{})

当前线程会不会等待队列里的线程回调执行完block,而是直接往下执行。

dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);

这个是指定时间执行,when为什么时候执行,可用dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC))填写when的值

执行一次

 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
        NSLog(@"----once,%@",[NSThread currentThread]);
 });

当onceToken为同一个token时,block只会被调用一次,block在当前线程中执行

队列组

当组里面的所有任务执行完了以后,会通知。

创建队列组

dispatch_group_t group = dispatch_group_create();

增加任务到组里面

dispatch_group_async(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);

等待组里面的任务执行完毕或执行完后通知

dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout); //当前线程阻塞等待执行完毕
dispatch_group_notify(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);//当前线程继续执行,执行完后得到通知

NSOperation

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        // 1.异步下载图片
        NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        
        // 2.回到主线程,显示图片
//        [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
//        dispatch_async(dispatch_get_main_queue(), ^{
//            
//        });
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
        }];
    }];
}

- (void)dependency
{
    /**
     假设有A、B、C三个操作,要求:
     1. 3个操作都异步执行
     2. 操作C依赖于操作B
     3. 操作B依赖于操作A
     */
    
    // 1.创建一个队列(非主队列)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.创建3个操作
    NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A1---%@", [NSThread currentThread]);
    }];
    //    [operationA addExecutionBlock:^{
    //        NSLog(@"A2---%@", [NSThread currentThread]);
    //    }];
    //
    //    [operationA setCompletionBlock:^{
    //        NSLog(@"AAAAA---%@", [NSThread currentThread]);
    //    }];
    
    NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B---%@", [NSThread currentThread]);
    }];
    NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C---%@", [NSThread currentThread]);
    }];
    
    // 设置依赖
    [operationB addDependency:operationA];
    [operationC addDependency:operationB];
    
    // 3.添加操作到队列中(自动异步执行任务)
    [queue addOperation:operationC];
    [queue addOperation:operationA];
    [queue addOperation:operationB];
}

- (void)maxCount
{
    // 1.创建一个队列(非主队列)
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.设置最大并发(最多同时并发执行3个任务)
    queue.maxConcurrentOperationCount = 3;
    
    // 3.添加操作到队列中(自动异步执行任务,并发)
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片1---%@", [NSThread currentThread]);
    }];
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片2---%@", [NSThread currentThread]);
    }];
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片3---%@", [NSThread currentThread]);
    }];
    NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载图片4---%@", [NSThread currentThread]);
    }];
    NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
    
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    [queue addOperation:operation4];
    [queue addOperation:operation5];
    [queue addOperationWithBlock:^{
        NSLog(@"下载图片5---%@", [NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"下载图片6---%@", [NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"下载图片7---%@", [NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"下载图片8---%@", [NSThread currentThread]);
    }];
    [queue addOperationWithBlock:^{
        NSLog(@"下载图片9---%@", [NSThread currentThread]);
    }];
    
    [queue cancelAllOperations];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    
//    [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
//    [queue setSuspended:YES]; // 暂停队列中的所有任务
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
//    [queue setSuspended:NO]; // 恢复队列中的所有任务
}

- (void)download
{
    NSLog(@"download---%@", [NSThread currentThread]);
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!