创建线程介绍及 GCD 简单使用

将耗时操作放到线程中进行:
1、NSThread

    // [NSThread currentThread] 获得当前线程,在开发中经常打印。 所有多线程技术都能使用这个方法
    // number == 1 主线程
    // number != 1 其他线程,子线程, 次线程    
    // 将耗时的操作放到子线程执行
    // 会开辟一个子线程,并且在子线程执行longTimeOperation方法,后面传递参数
    [self performSelectorInBackground:@selector(longTimeOperation) withObject:nil];


// 创建线程方式1
- (void)test1
{
    // 实例化一个线程对像
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

    // 让线程开始工作,启动线程, 在新开的线程执行run方法
    [thread start];
}
// 创建线程方式2
- (void)test2
{
    NSLog(@"---%@", [NSThread currentThread]);
    [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"hello"];

    NSLog(@"test2 --- %@", [NSThread currentThread]);
}
// 创建线程方式3
- (void)test3
{
    // “隐式”创建线程方式
    [self performSelectorInBackground:@selector(run:) withObject:@"cz"];
}

2、pthread

    // 声明一个线程变量
    pthread_t threadId;
    /*
     参数:
     1. 要开的线程的变量
     2. 线程的属性
     3. 要在这个子线程执行的函数(任务)
     4. 这个函数(任务)需要传递的参数
     */

//    pthread_create(,, , <#void *restrict#>)

    id str = @"hello";


    // id需要转成void *,在ARC里,需要使用__bridge 进行桥联
    // 1. 这里只是临时把str对象专程void *在这里临时使用。 不改变这个对象(str)的所有权。
    // 2. 把对象的所有权交出去,在这个函数把str转成void *
    // 如果使用MRC,这里不需要桥联,可以直接设置这个参数
    // ARC自动内存管理,本质是编译器特性。是在程序编译的时候,编译器帮我们在合适的地方添加retain,release,autorelease。
    pthread_create(&threadId, NULL, run, (__bridge void *)(str));

// 函数
void *run(void *param)
{
    NSString *str = (__bridge NSString *)(param);

    // 耗时操作放在这里执行
    for (int i = 0; i < 20000; i++) {
        NSLog(@"%@----%@", [NSThread currentThread], str);
    }

    return NULL;
}

GCD:
队列:把任务放到队列里面,队列先进先出的原则,
串行队列:顺序,一个一个执行(必须一个任务执行完了,才能从队列里面取出下一个任务)
并发队列:同时,同时执行很多个任务(可以同时取出很多个任务,只要有线程去执行)

同步sync:不会开新线程
异步async:会开新线程,多线程的代名词

串行队列同步执行:不开线程,在原来线程里面一个一个顺序执行
串行队列异步执行:开一条线程,在这个新线程里面一个一个顺序执行
并发队列异步执行:开多个线程,并发执行(不一定是一个一个)执行
并发队列同步执行:不开线程,在原来线程里面一个一个顺序执行

/**
 串行队列:顺序,一个一个执行
 同步任务:不会开辟新线程,是在当前线程执行
 结果:不开新线程,在当前线程顺序执行

 dispatch : 调度,GCD里面函数,都是以dispatch开头的
 */
     // 1. 创建一个串行队列
    //参数:1. 队列标签 2. 队列的属性
    dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);

    // 2. 同步执行任务
    // 一般只要使用”同步“执行,串行队列对添加的同步任务,会立马执行
    dispatch_sync(queue, ^{
        NSLog(@"%@", [NSThread currentThread]);
    });
/**
 串行队列:一个一个执行
 异步执行:肯定会开新线程,在新线程执行
 结果:只会开一个线程,而且所有任务都在这个新的线程里面执行
 */
     // 1. 串行队列
    // 下面两种写法是一样的
//    dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue = dispatch_queue_create("itcast", NULL);


    // 2. 异步执行
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }
/**
  并发队列:可以同时执行多个任务
  同步任务:不会开辟新线程,是在当前线程执行
  结果:不开新线程,顺序一个一个执行。
 */
    //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);
        });
    }
/**
 并发队列:可以同时执行多个任务
 异步执行:肯定会开新线程,在新线程执行
 结果:会开很多个线程,同时执行
 */
     //1. 并行队列
    dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);

    // 2. 异步执行任务
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%@ %d", [NSThread currentThread], i);
        });
    }

总结:1. 开不开线程,由执行任务方法决定,同步不开线程,异步肯定开线程;
2. 开多少线程,由队列决定,串行 最多 开一个线程, 并发可以开多个线程。 具体开多少个,有GCD底层决定。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值