NSThread , GCD 与NSOparetion

本文深入探讨了iOS开发中的多线程技术,包括NSThread、GCD和NSOperation等主流方案的特点及应用场景,帮助开发者更好地理解如何进行线程管理和任务调度。

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

1.NSThead

// 第一种方式

// 开辟线程需要消耗CPU的资源


// 先去需要一个入口函数,作为切入点


// 这种方式创建的线程需要手动执行


_thread = [[NSThread alloc] initWithTarget:self selector:@selector(doSemoThing) object:nil];


// 给线程设置名称


_thread.name = @"do semo thing thread";


// 执行线程

[_thread start];

// 第二种方式

// 自动执行

[NSThread detachNewThreadSelector:@selector(doSemoThing) toTarget:self withObject:nil];

// 第三种方式

// 自动执行

[self performSelectorInBackground:@selector(downloadImage) withObject:nil];

回主线程 ,通讯
[self performSelectorOnMainThread:@selector(reloadUI) withObject:nil waitUntilDone:NO];

// 在指定函数去执行某个方法

self performSelector:<#(SEL)#>



 // 判断是否有取消的标识位

    if ([_thread isCancelled]) {

        // 退出当前线程

        // 退出之后下面的代码就再执行,类似return

        [NSThread exit];

    }

    // 睡秒1秒

    sleep(1.0f);

    // 微秒为单位

// usleep(<#useconds_t#>)

    // 睡眠多久

    [NSThread sleepForTimeInterval:1.0];

    // 以当前时间为基准,向后偏移10秒

   NSDate *date = [[NSDate date] dateByAddingTimeInterval:10.0f];

    // 指定睡眠到什么时候

   [NSThread sleepUntilDate:date];

2.GCD

Grand Central Dispatch 全局中央调度

GCD 是苹果以解决多核并发一种解决方案,能够自动帮我们管理线程(线程的创建,调度,销毁)

使用GCD两个重要的概念

 任务 - 做什么(代码部分)

 队列 - 管理任务,怎么做

 任务分为两种

 同步 - 需要等待上一个任务的完成,下面的任务才能执行

 异步 - 不需要等待     

 区别 - 会不会阻塞线程

 队列也分为两种

 串行 - 一个一个地执行

 并行 - 同时执行

// 核心概念:

// 任务:block

// 队列:把任务放到队列里面,队列先进先出的原则,

// 串行队列:顺序,一个一个执行(必须一个任务执行完了,才能从队列里面取出下一个任务)

// 并发队列:同时,同时执行很多个任务(可以同时取出很多个任务,只要有线程去执行)

// 同步sync:不会开新线程

// 异步async:会开新线程,多线程的代名词

// 串行队列同步执行:不开线程,在原来线程里面一个一个顺序执行

// 串行队列异步执行:开一条线程,在这个新线程里面一个一个顺序执行

// 并发队列异步执行:开多个线程,并发执行(不一定是一个一个)执行

// 并发队列同步执行:不开线程,在原来线程里面一个一个顺序执行

// 阶段性总结:

// 1. 开不开线程,由执行任务方法决定,同步不开线程,异步肯定开线程

// 2. 开多少线程,由队列决定,串行 最多 开一个线程, 并发可以开多个线程。 具体开多少个,有GCD底层决定,程序猿不能控制

// 获取主队列(串行)

dispatch_queue_t mainQueue = dispatch_get_main_queue();

// 创建一个队列

/**

 创建一个新队列

 参数1 队列的名字

 参数2 队列的类型

 DISPATCH_QUEUE_SERIAL      串行

 DISPATCH_QUEUE_CONCURRENT  并行

 */

dispatch_queue_t newQueue = dispatch_queue_create("com.dispatch.newQueue", DISPATCH_QUEUE_SERIAL);



// 全局队列(并行),一般没有特定的要求,都使用全局队列

/**

 参数1 优先级

 DISPATCH_QUEUE_PRIORITY_DEFAULT    默认的

 DISPATCH_QUEUE_PRIORITY_HIGH       优先级高

 DISPATCH_QUEUE_PRIORITY_LOW        优先级低

 DISPATCH_QUEUE_PRIORITY_BACKGROUND 最低的优先级



 参数2

 系统保留的参数0

 */

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

/**

串行队列:顺序,一个一个执行

同步任务:不会开辟新线程,是在当前线程执行

结果:不开新线程,在当前线程顺序执行

dispatch : 调度,GCD里面函数,都是以dispatch开头的

*/

  • (void)gcdTest1

{

// 1. 创建一个串行队列

//参数:1. 队列标签 2. 队列的属性

dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);



 NSLog(@"开始!!");



// 2. 同步执行任务



// 一般只要使用”同步“执行,串行队列对添加的同步任务,会立马执行

dispatch_sync(queue, ^{

    NSLog(@"%@", [NSThread currentThread]);

});



NSLog(@"完成!!");

}

/**

串行队列:一个一个执行

异步执行:肯定会开新线程,在新线程执行

结果:只会开一个线程,而且所有任务都在这个新的线程里面执行

*/

  • (void)gcdTest2

{

// 1. 串行队列

// 下面两种写法是一样的

// dispatch_queue_t queue = dispatch_queue_create(“itcast”, DISPATCH_QUEUE_SERIAL);

dispatch_queue_t queue = dispatch_queue_create(“itcast”, NULL);

// 创建全局队列。 全局队列是并行的、

dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

NSLog(@"%@ %d", [NSThread currentThread]);





// 2. 异步执行

for (int i = 0; i < 10; i++) {

    dispatch_async(queue, ^{

        NSLog(@"%@ %d", [NSThread currentThread], i);

    });

}

}

/**

并发队列:可以同时执行多个任务

异步执行:肯定会开新线程,在新线程执行

结果:会开很多个线程,同时执行

*/

  • (void)gcdTest3

{

//1. 并行队列

dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);

dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 2. 异步执行任务

for (int i = 0; i < 10; i++) {

    dispatch_async(queue, ^{

        NSLog(@"%@ %d", [NSThread currentThread], i);

    });

}

}

/**

并发队列:可以同时执行多个任务

同步任务:不会开辟新线程,是在当前线程执行

结果:不开新线程,顺序一个一个执行。

*/

  • (void)gcdTest4

{

//1. 并行队列

dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);



// 2. 同步执行任务

for (int i = 0; i < 10; i++) {

    dispatch_sync(queue, ^{

        NSLog(@"%@ %d", [NSThread currentThread], i);

    });

}

}

// 任务…

// 当组中所有的任务执行完后

// 通过我们设定好的通知告诉我们

dispatch_group_notify(group, queue, ^{

    NSLog(@"执行完毕");

    // 回到主线程刷新UI

    dispatch_async(dispatch_get_main_queue(), ^{

        self.view.backgroundColor = [UIColor redColor];

    });

});

// 延迟执行。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

});

3.NSOparetion
NSOperation是基于GCD封装的一套OC语言的队列间接管理线程的方式

NSOperation 三种类型

1.NSBlockOperation,以block为任务执行的操作

2.NSInvocationOperation,以SEL方法为任务的执行操作

3.NSOpertion 作为父类,创建子类的自定义任务,例子:AFNetworking 上的AFHTTPRequestOperation

NSOperation 比GCD增加

1.cancel 取消任务

2.addDependency 任务依赖

3.waitUntilAllOperationsAreFinished 等待任务完成

4.maxConcurrentOperationCount 最大并发数

NSOperation 官方推荐使用NSOperation处理事件大并发的情况

// NSOperation是一个抽象的父类,不要去直接使用

// 应该使用它的子类NSIvocationOperation,NSBlockOpreation



// 方式1

NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSemoThing) object:nil];

// 手动去执行

// [invocation start];

// 方式2

// 利用bolck的方式去创建线程

NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{



    int i = 10;

    while (i--) {

        NSLog(@"block operation %d", i);

        [NSThread sleepForTimeInterval:1.0];

    }

}];



// 执行

// [block start];

// 创建队列,用来管理任务

NSOperationQueue *queue = [[NSOperationQueue alloc] init];



// 设置队列的最大并发数

queue.maxConcurrentOperationCount = 5;



// 如果需要设置任务之间依赖关系,需要在添加到队列之前设置

// 前者依赖后者,只有后者执行完,前者才会取执行

[invocation addDependency:block];



// 将任务加入到队列中,队列会自动创建线程,并将队列中的任务取出放在线程中执行

[queue addOperation:invocation];



// 队列中的任务可以添加N个,队列会为每个任务创建一个线程

[queue addOperation:block];



// 如果有需要可以取消线程

// [invocation cancel];

// [block cancel];

// 取消队列中所有的线程

// [queue cancelAllOperations];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值