iOS进阶之多线程

进程

  • 一个进程有一个或多个线程组成。进程只负责资源的调度和分配,线程才是程序正在的执行单元,负责代码的执行。
  • 单线程 只有一个线程的程序,称作为单线程程序。
  • 多线程 iOS允许用户自己开辟新的线程,相当于主线程来讲。这些线程,称为子线程;子线程和主线程都是独立的运行单元,各自的执行互不影响,因此能够并发执行。
  • iOS中关于UI的添加和刷新必须在主线程中操作

创建子线程

 //创建子线程
  self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(subThread:) object:@"子线程启动"];
//启动子线程
 [self.thread start];

GDC的学习

#pragma mark --- GCD的学习
//穿行队列:所有的任务在队里中顺序执行,相当于在operationQueue中将最大并大数设置为1的效果
//并行队列:所有的任务都是在队列中并发执行。
-(void)serialQueue{
    //创建穿行队列
    //第一个参数:当前队列的标记
    //第二个参数:当前队列的类型设置 DISPATCH_QUEUE_SERIAL宏定义的值为NULL
//    dispatch_queue_t sQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    
    //创建并行队列
    dispatch_queue_t sQueue = dispatch_queue_create("conCurrent", DISPATCH_QUEUE_CONCURRENT);
    //创建任务添加到队列中
    //第一个参数:当前任务所要添加进的队列
    //第二个参数:block,要执行的任务在block中执行
    dispatch_async(sQueue, ^{
        NSLog(@"1----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"2----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"3----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"4----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"5----%@",[NSThread currentThread]);
    });
    dispatch_async(sQueue, ^{
        NSLog(@"6----%@",[NSThread currentThread]);
    });
}
//全局队列 系统提供的一个并行队列,该全局队列,可以设置队列优先级
-(void)globalQueue{
    
    //第一个参数:优先级设置
    //第二个参数:预留参数,将来可能用到。目前直接赋值为0即可
    dispatch_queue_t gQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(gQueue, ^{
        NSLog(@"要执行的耗时操作----%@",[NSThread currentThread]);
        //回主线程处理UI
        //先得到一个主队列,将任务加入到主队列,在主队列执行的任务肯定在主线程中。
        dispatch_queue_t mainQueue = dispatch_get_main_queue();
        dispatch_async(mainQueue, ^{
            NSLog(@"我回到主线程了----%@",[NSThread currentThread]);
        });
    });
    //简便写法。工作中经常用到的写法
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //处理耗时操作
        
        //处理完数据回主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            //回到主线程处理UI操作
        });
    });             
}
//延迟执行
-(void)delayAction{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"延迟执行----%@",[NSThread currentThread]);
    });
}
//某段代码执行一次
-(void)onceToken{
    for (int i = 0; i < 10; i++) {
        
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken,^{
            NSLog(@"某段代码执行一次");
        });
    }
}
//单列中GCD的应用
+(OperationQueueViewController*)sharedOperationQueueViewController{
    static OperationQueueViewController* vc = nil;
    //加线程锁也可以将该对象全局唯一,不会重复出现;但是效率比较低。由于效率低,所有我们一般不使用这种方式
//    @synchronized(self) {
//        if (vc == vc) {
//            vc = [[OperationQueueViewController alloc] init];
//        }
//    }
    //官方推荐的单例的写法
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //该block中代码只会被执行一次
        vc = [[OperationQueueViewController alloc] init];
    });
    return vc;
}

任务队列

//任务队列:任务队列可以管理一组任务,它会根据当前的情况为任务开辟合适数量的子线程来完成任务,在队列中的任务,不需要手动启动。
//任务队列一般分为两种:主队列和其它队列。主队列:在主队列中的任务一定是在主线程中执行;其它队列:其它队列中的任务,一定是在子线程中执行。
//主队列
-(void)studyMainQueue{
    //创建主队列对象
    NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
    NSBlockOperation* blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"5----%@",[NSThread currentThread]);
    }];
    //将任务加入到队列中,任务不用手动启动
//    [mainQueue addOperation:blockOperation_1];
//    [mainQueue addOperation:blockOperation_2];
//    [mainQueue addOperation:blockOperation_3];
//    [mainQueue addOperation:blockOperation_4];
//    [mainQueue addOperation:blockOperation_5];
    //主队列等待当前所在线程操作执行完毕之后,在执行队列中的任务
    //主线程在等主队列中的任务执行完了,在接着做其它操作
    //线程阻塞
    NSLog(@"bbbb");
    //YES:有可能会造成线程的阻塞
    //NO:主线程无需等待任务执行完成,不会造成线程阻塞
    [mainQueue addOperations:@[blockOperation_1,blockOperation_2,blockOperation_3,blockOperation_4,blockOperation_5] waitUntilFinished:NO];
    NSLog(@"aaa");
}
//其它队列:一定在子线程中执行,任务是并发执行,没有先后顺序之分
-(void)studyOttheQueue{
    //队列对象
    NSOperationQueue* ohterQueue = [[NSOperationQueue alloc] init];
    //创建任务添加到队列中
    NSBlockOperation* blockOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4----%@",[NSThread currentThread]);
    }];
    NSBlockOperation* blockOperation_5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"5----%@",[NSThread currentThread]);
    }];
    //如果某些任务是有先后顺序的,我们可以为任务添加依赖关系
    //两个任务不能互相为依赖,否则,两个任务都不会执行
//    [blockOperation_2 addDependency:blockOperation_1];
//    [blockOperation_3 addDependency:blockOperation_2];
//    [blockOperation_4 addDependency:blockOperation_3];
//    [blockOperation_5 addDependency:blockOperation_4];
    //如果想要所有的任务添加顺序执行,设置最大并大数
    [ohterQueue setMaxConcurrentOperationCount:1];
    //将任务加入到队列中,任务不用手动启动
    [ohterQueue addOperation:blockOperation_1];
    [ohterQueue addOperation:blockOperation_2];
    [ohterQueue addOperation:blockOperation_3];
    [ohterQueue addOperation:blockOperation_4];
    [ohterQueue addOperation:blockOperation_5];
}

NSInvocationOperation任务对象

//NSInvocationOperation 任务对象,本身和线程无关,通过target—action的方法执行一个任务,需要调用start方法启动任务。
-(void)invocationOperation{
    //初始化任务对象
    NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationAction:) object:@"invocation"];
    //启动任务
    [operation start];
    
}
-(void)invocationAction:(NSString*)sender{
    NSLog(@"sender----%@",sender);
    NSLog(@"当前线程为:%@,是否是主线程:%d",[NSThread currentThread],[NSThread isMainThread]);
}
//NSBlockOPeration.和invocationOperation基本一致,只是通过block来实现操作
-(void)blockOperation{
    NSBlockOperation* bOperation = [NSBlockOperation blockOperationWithBlock:^{
//        NSLog(@"");
        NSLog(@"blockOperation---%@",[NSThread currentThread]);
    }];
    //启动任务
    [bOperation start];
}

你可能感兴趣的:(iOS进阶之多线程)