您的位置:首页 > 其它

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

2016-05-28 15:58 411 查看
将耗时操作放到线程中进行:

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底层决定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gcd 线程