UI进阶——多线程
来源:互联网 发布:游戏数据分析报告 编辑:程序博客网 时间:2024/05/17 04:21
一、多线程的概念
线程就是指每个独立运行的代码片;
每个赈灾运行的程序(即进程),至少包含一个线程,这个线程为主线程。
只有一个主线程的程序,称为单线程程序。
拥有多个线程的程序,称为多线程程序。
多个线程可以并发执行。
注意:
iOS中关于UI的添加和刷新必须在主线程中操作。
iOS中多线程的种类有四种:
NSThread
NSOperationQueue(是队列,没有开辟线程的能力)
NSObject
GCD
二、NSThread
demo:
-(void)tesr{ UIImageView* imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1.jpg"]]; [self.view addSubview:imageView]; //轻量级的多线程调用方法,当使用alloc init的方式,需要手动启动,便利构造器的方式不需要手动启动 //object,是线程回调方法的参数,如果不需要参数,直接赋予值为nil; NSThread* forThread = [[NSThread alloc]initWithTarget:self selector:@selector(forMethod) object:nil]; forThread.name = @"我是老二"; //线程优先级,0到1.0 forThread.threadPriority = 1.0; //启动线程 [forThread start]; //得到当前线程的信息 NSLog(@"imageThread---%@",[NSThread currentThread]); NSMutableArray* array = [NSMutableArray array]; for (int j = 1; j<11; j++) { UIImage * item = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",j]]; [array addObject:item]; } imageView.animationImages = array; imageView.animationDuration = 2.0; // imageView.animationRepeatCount = 10; //启动动画 [imageView startAnimating];}
//循环一亿次-(void)forMethod{ NSLog(@"forThread---%@",[NSThread currentThread]); for(int i = 0;i<1000000;i++){ NSLog(@"%d",i); }}
效果就是可以看到动图的加载并不受循环的影响,这就是线程的意义。
demo:
记住线程如果是我们自己开辟的,那么即使在mrc模式下,也需要将其放入自动释放池中。
//nsthread学习-(void)threadStudy{ //便利构造器的方式,五返回值 [NSThread detachNewThreadSelector:@selector(thread_1Action:) toTarget:self withObject:@"thread_1"]; //通过alloc的方式创建 NSThread *thread_2 = [[NSThread alloc]initWithTarget:self selector:@selector(thread_2Action:) object:@"thread_2"]; [thread_2 start]; thread_2.name = @"最优先"; thread_2.threadPriority = 1.0; [NSThread detachNewThreadSelector:@selector(thread_3Action:) toTarget:self withObject:@"thread_3"];}-(void)thread_1Action:(NSString*)string{ //当子线程是我们手动开辟的,那么就需要我们自己管理内存 @autoreleasepool { NSLog(@"%@",[NSThread currentThread]); NSLog(@"%@",string); } }-(void)thread_2Action:(NSString*)string{ @autoreleasepool { NSLog(@"%@",[NSThread currentThread]); NSLog(@"%@",string); }}-(void)thread_3Action:(NSString*)string{ @autoreleasepool { NSLog(@"%@",[NSThread currentThread]); NSLog(@"%@",string); }}
记住线程如果是我们自己开辟的,那么即使在mrc模式下,也需要将其放入自动释放池中。
三、NSObject
//NSObject的多线程方式// 1.从主线程进入子线程 [self performSelectorInBackground:@selector(objectAction:) withObject:@"090987开辟子线程的方式"];
在objectAction方法中,写代码并回到主线程:
-(void)objectAction:(NSString*)string{ NSLog(@"参数%@",string); //从子线程中回到主线程 /** * Description * * @param BOOL yes:只有回主线程的回调方法执行结束才执行下面的操作。NO:与之相反 * * @return 没有返回值 */ [self performSelectorOnMainThread:@selector(backMainAction) withObject:nil waitUntilDone:NO]; NSLog(@"我是在回主线程的底下打印的");}
四、GCD
demo:
//串行队列,一次只执行一个任务-(void)serialQueue{ //创建串行队列 /** * Description * * @param label#> 当前队列的标签 description#> * @param attr#> 字符 description#> * * @return 返回一个dispatch_queue_t */ dispatch_queue_t serialQueue = dispatch_queue_create("串行队列",DISPATCH_QUEUE_SERIAL); //为串行队列添加任务 dispatch_async(serialQueue, ^{ NSLog(@"你好------%@",[NSThread currentThread]); }); //异步任务 dispatch_async_f(serialQueue, "建华会说话了", function); dispatch_async(serialQueue, ^{ NSLog(@"会上学了%@",[NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"结婚了%@",[NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"被全退了%@",[NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"堕落了%@",[NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"洗心革面了%@",[NSThread currentThread]); }); dispatch_async(serialQueue, ^{ NSLog(@"出家了%@",[NSThread currentThread]); }); NSLog(@"我在最下面你%@",[NSThread currentThread]);}//定义一个回调函数void function(void* str){ printf("%s\n",str);}//创建并行队列-(void)concurrentQueue{ //创建并行队列 dispatch_queue_t concurrentQueue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT); //同步任务所处的线程就是当前线程 dispatch_async(concurrentQueue, ^{ NSLog(@"你好------%@",[NSThread currentThread]); }); //异步任务 dispatch_async_f(concurrentQueue, "建华会说话了", function); dispatch_async(concurrentQueue, ^{ NSLog(@"会上学了%@",[NSThread currentThread]); }); dispatch_async(concurrentQueue, ^{ NSLog(@"结婚了%@",[NSThread currentThread]); }); dispatch_async(concurrentQueue, ^{ NSLog(@"被全退了%@",[NSThread currentThread]); }); dispatch_async(concurrentQueue, ^{ NSLog(@"堕落了%@",[NSThread currentThread]); }); dispatch_async(concurrentQueue, ^{ NSLog(@"洗心革面了%@",[NSThread currentThread]); }); dispatch_async(concurrentQueue, ^{ NSLog(@"出家了%@",[NSThread currentThread]); }); }//系统提供的队列,全局队列-(void)globalQueue{ //系统提供的一个全局队列 //参数一,权限,即优先级 2,0 ,-2,INT16_MIN。参数二,系统预留 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //添加任务 //全局队列是一个系统提供的并行队列 dispatch_async(globalQueue, ^{ NSLog(@"*******--------------%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"*******------36736735736737%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"*******-37373756473637635%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"******6666666666666666%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"****555555555555555%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"*******------%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"*******----%@",[NSThread currentThread]); }); dispatch_async(globalQueue, ^{ NSLog(@"*******%@",[NSThread currentThread]); }); }- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}//gcd常见的使用方式,全局队列和主队列结合使用-(void)globalAndMainQueue{ dispatch_async(dispatch_get_global_queue(0, 0), ^{ //在全局队列里执行耗时的操作,因为全局队列执行的任务是在子线程中,不会阻塞主线程 dispatch_async(dispatch_get_main_queue(), ^{ //该block中所执行的任务是在主队列中执行,那么该任务是在主线程中执行,在此处进行刷新UI的行为。 }); });}//gcd中让某些代码执行一次-(void)onceToken{ static UIImage* image = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //此处的代码只执行一次 image = [[UIImage alloc]init]; });}//其他的方法-(void)otherGCD{ //延时执行的 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"五秒真男人"); }); //重复执行 dispatch_apply(3, dispatch_get_global_queue(0,0), ^(size_t size) { NSLog(@"五秒再来一次"); }); }
五、队列
demo:
//invocation的回调方法-(void)invocationAction{ //打印当前的线程 NSLog(@"%@-------判断是否为主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);}//operation和operationQueue-(void)operationQueue{ //初始化一个任务target - action operation并没有开辟线程,将operation在那个线程中使用,operation所在的线程就是当前线程。 NSInvocationOperation* invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction) object:nil]; //当加入队列的时候,不需要手动启动,在队列则不用手动启动 [invocation start]; //操作的block的方式 NSBlockOperation* blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@------",[NSThread currentThread]); }]; //添加多个block操作,当使用addExecutionBlock为BlockOPeration添加可执行的block的时候,这些可执行的block会在当前线程,或者其他子线程中进行。 //在启动之前添加事件 for (int i=0; i<10; i++) { [blockOperation addExecutionBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],i); }]; }; blockOperation.completionBlock = ^(){ NSLog(@"我就是最后一个,你们随便折腾"); }; //启动操作 [blockOperation start]; NSLog(@"我是在最底下");}//queue的学习,队列 nsoperationQuene 是对gcd的一个oc级别的封装。-(void)operationOperationQuene{ //先初始化队列对象,(其他队列:除了主队列,自己初始化的队列都是其他队列) NSOperationQueue *otherQueue = [[NSOperationQueue alloc]init]; //队列的最大并发数,在同一时刻最多可执行的操作// otherQueue.maxConcurrentOperationCount = 1; //创建可执行的操作对象 /*for (int i=0; i<10; i++) { NSBlockOperation* blockopeartion = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],i); }]; //将block操作添加到队列中去 [otherQueue addOperation:blockopeartion]; };*/ NSBlockOperation* blockopeartion_0 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],0); }]; NSBlockOperation* blockopeartion_1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],1); }]; NSBlockOperation* blockopeartion_2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],2); }]; NSBlockOperation* blockopeartion_3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],3); }]; NSBlockOperation* blockopeartion_4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],4); }]; //为时间添加依赖关系,先添加依赖,在添加事件到队列中 [blockopeartion_4 addDependency:blockopeartion_3]; //当操作对象添加到队列中之后,就不需要手动启动了 [otherQueue addOperation:blockopeartion_0]; [otherQueue addOperation:blockopeartion_1]; [otherQueue addOperation:blockopeartion_2]; [otherQueue addOperation:blockopeartion_3]; [otherQueue addOperation:blockopeartion_4];}//主队列-(void)mainQueue{ NSLog(@"%@",[NSThread currentThread]); //先创建主队列的对象 NSOperationQueue* mainQueue = [NSOperationQueue mainQueue]; for (int i = 0 ; i < 10 ; i ++) { NSBlockOperation* blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@-----%d",[NSThread currentThread],i); }]; [mainQueue addOperation:blockOperation]; }}
0 0
- UI进阶——多线程
- UI进阶 —— 收起键盘方法
- UI进阶——数据请求
- UI进阶——SQL数据库
- UI进阶——XMPP即时通讯
- UI进阶——地图的使用
- UI 多线程——种类
- C++进阶—>C++中的多线程
- Android UI组件进阶(2)——仿Windows对话框
- UI进阶——XML解析与Json解析
- UI进阶——数据的加解密
- UI进阶——第三方的使用
- UI进阶——Style的详细介绍
- IOS开发UI进阶篇 — 广告轮播器
- IOS开发UI进阶篇 — 原生二维码、条形码扫描
- java多线程—概念—菜鸟的进阶
- 【J2SE快速进阶】——Java多线程机制
- 【J2SE快速进阶】——多线程之synchronized
- 极路由的“802.1x手机号登陆wifi”插件,电脑连接wifi方法
- servlet中请求转发(forword)与重定向(sendredirect)的区别
- LINUX编程学习路线
- gson处理多层嵌套的复杂形式的json
- C++类型转换机制
- UI进阶——多线程
- ok6410时钟初始化
- 财政部关于印发《公益事业捐赠票据使用管理暂行办法》的通知
- hdu 1312 DFS深度搜索典型例题
- GIT 之常用用法
- C语言学习笔记之格式化I/O(scanf函数、printf函数)
- UVA 1423 Guess 拓扑排序
- webView 网页加载方式
- 视觉SLAM漫谈