iOS 开发之多线程的应用场景

来源:互联网 发布:ping用的是什么端口 编辑:程序博客网 时间:2024/05/22 00:07
  1. <pre name="code" class="objc">   通过下面一个例子来了解一下多线程的应用场景,我们可以通过点击按钮来开始或者暂停动画的播放,但是当我们点击另一个按钮时,  
  2. 就会执行一个方法,在该方法中循环打印一个很大的数字,在打印过程中,再通过点击播放/暂停按钮来控制动画已经无法做到了  
  3. ,这时屏幕已经卡死,必须等待打印完成,才能控制动画的播放。如何既能打印又能控制动画的播放那,可以利用多线程来完成,  
  4. 将打印交给子线程去完成就可以了,下面讲了几种简单开启的子线程方法,非常详细。在进入例子之前先来了解一下线程的基础知识。  
  5. <pre name="code" class="objc">/** 
  6.  *  进程:一个正在运行的程序,叫一个进程 
  7.     多进程:多个程序正在运行,叫多进程 
  8.     线程:一个程序或者说一个进程 都会有一个或多个线程 如果只有一个 我们叫他主线程 主线程负责用户能看见的任务 例如添加控件 刷新页面,除了主线程以外 
  9. 都叫子线程, 线程之间是独立的没有任何联系,子线程一般负责用户不直接看到的任务 例如加载图片的过程 下载视频等。 
  10.  线程要明确的:只要用户看得见的 或者 跟用户看得见有关的 都使用主线程 进行操作。 因为开启子线程操作的时候 是为了更好地用户体验  
  11. 用户体验直接的表现为看到的或者点击的流畅性。 
  12.  线程是耗费资源的,虽然可以多线程操作 可以提高用户体验 但是不建议 进行很多线程同时进行操作。 
  13.  */  
  14.   
  15. #import "RootViewController.h"  
  16.   
  17. @interface RootViewController ()  
  18.   
  19. // 声明一个imageView  
  20. @property (nonatomicretainUIImageView *imageView;  
  21.   
  22. @end  
  23.   
  24. @implementation RootViewController  
  25.   
  26.   
  27.   
  28. -(void)dealloc  
  29. {  
  30.     [_imageView release];  
  31.     [super dealloc];  
  32. }  
  33.   
  34. - (void)viewDidLoad {  
  35.     [super viewDidLoad];  
  36.   
  37.     [self addSubviews];  
  38.   
  39. }  
  40.   
  41. // 创建imageView并添加图片按钮  
  42. - (void)addSubviews  
  43. {  
  44.     self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50100200200)];  
  45.     self.imageView.backgroundColor = [UIColor redColor];  
  46.     [self.view addSubview:self.imageView];  
  47.     [_imageView release];  
  48.       
  49.     // 播放一组图片  
  50.     NSMutableArray *imageArray = [NSMutableArray array];  
  51.     for (int i = 0; i < 3; i++) {  
  52.         UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"pic%d", i + 4]];  
  53.         // 加进数组  
  54.         [imageArray addObject:image];  
  55.     }  
  56.     // 设置播放属性  
  57.     self.imageView.animationImages = imageArray;  
  58.     self.imageView.animationDuration = 0.5;  
  59.     self.imageView.animationRepeatCount = 0;  
  60.       
  61.     // 点击按钮 开始播再点击按钮停止播  
  62.       
  63.     UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];  
  64.     button.frame = CGRectMake(1003205050);  
  65.     button.backgroundColor = [UIColor blueColor];  
  66.     [button setTitle:@"播放" forState:UIControlStateNormal];  
  67.     [button setTitle:@"停止" forState:UIControlStateSelected];  
  68.     [button addTarget:self action:@selector(actionButton:) forControlEvents:UIControlEventTouchUpInside];  
  69.     [self.view addSubview:button];  
  70.       
  71.     // 点击另一个按钮 循环打印  
  72.     UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];  
  73.     button1.frame = CGRectMake(1603205050);  
  74.     button1.backgroundColor = [UIColor blueColor];  
  75.     [button1 setTitle:@"打印" forState:UIControlStateNormal];  
  76.     [button1 addTarget:self action:@selector(actionPrint:) forControlEvents:UIControlEventTouchUpInside];  
  77.     [self.view addSubview:button1];  
  78.       
  79.     //需要一边打印 一边还能 开关动画  
  80.     // 解决方案:开启一个子线程去完成打印的工作  
  81. #pragma mark ----NSThread----  
  82.     // 这是一个最轻量级的线程 可以开启线程和关闭线程  
  83.     // 创建一个线程 就是给他一个方法去执行  
  84.     // 创建一个子线程专门去打印  
  85.     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(actionPrint:) object:nil];  
  86.     // 开启这个线程  
  87.    [thread start];  
  88.     // 注意:线程操作的时候  
  89.     // 在主线程的时候 系统自动添加了一个 自动释放池 那么咱们在开启子线程的时候 也要添加一个自动释放池  
  90.     // 如果你的线程开的比较多 会造成代码比较乱 阅读性不高  
  91.     // 一般方法中 添加了自动释放池 基本上都是线程方法  
  92.       
  93. #pragma mark ---NSObject  
  94.     //NSObject也提供了开启线程的方法 也可以解决程序卡死问题  
  95.     [self performSelectorInBackground:@selector(actionPrint:) withObject:nil];  
  96.     //NSOperation也是抽象类 没有实现具体功能  
  97.     //NSInvocationOperation 调用操作(相当于任务)  
  98.     //NSBlockOperation block操作(相当于任务)  
  99.     //NSOperationQueue 线程队列  
  100.     //创建任务一  
  101.     NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocation1) object:nil];  
  102.       
  103.     // 创建任务二  
  104.     NSBlockOperation *blockOP2 = [NSBlockOperation blockOperationWithBlock:^{  
  105.         // block 块中 就相当于添加了任务  
  106.         [self blockOP2];  
  107.     }];  
  108.       
  109.     // 创建一个队列  
  110.     NSOperationQueue *queue = [[NSOperationQueue alloc] init];  
  111.     // 注意 添加任务前要设置依赖关系  
  112.     // 依赖性(串行)  
  113.     [invocation addDependency:blockOP2]; // 前面完成 后面才能开始  
  114.     // 把任务添加到队列当中  
  115.     [queue addOperation:invocation];  
  116.     [queue addOperation:blockOP2];  
  117.     // 设置线程最大并发数  
  118.     queue.maxConcurrentOperationCount = 2;  
  119.       
  120.     // 需求 进行同步请求一张图片 不产生屏幕卡顿  
  121.     // 思路:开启一个子线程 进行同步请求图片 图片加载完成后回到主线程 显示到imageView上  
  122.       
  123. }  
  124. // 实现任务一  
  125. - (void)invocation1  
  126. {  
  127.     // 子线程中添加一个自动释放池  
  128.     @autoreleasepool {  
  129.     //[NSThread currentThread] 当前线程的信息  
  130.     //打印是否是主线程  
  131.     // 打印出来的number 是线程的个数 第几个线程  
  132.     NSLog(@"%@ 是不是主线程:%d", [NSThread currentThread], [NSThread isMainThread]);  
  133.           
  134.     }  
  135. }  
  136. // 创建任务二  
  137. - (void)blockOP2  
  138. {  
  139.     @autoreleasepool {  
  140.           
  141.     NSLog(@"%@ 是不是主线程:%d", [NSThread currentThread], [NSThread isMainThread]);  
  142.           
  143.     }  
  144. }  
  145. // 点击按钮 开始播再点击按钮停止播  
  146. - (void)actionButton:(UIButton *)button  
  147. {  
  148.     button.selected = !button.selected;  
  149.     if (button.selected == YES) {  
  150.           
  151.         [self.imageView startAnimating];  
  152.   
  153.     } else {  
  154.           
  155.         [self.imageView stopAnimating];  
  156.     }  
  157. }  
  158.   
  159. // 循环打印 卡死程序  
  160. - (void)actionPrint:(UIButton *)button  
  161. {  
  162.     // 添加一个自动释放池  
  163.       
  164.     @autoreleasepool {  
  165.        for (int i = 0; i < 888888888; i++) {  
  166.         NSLog(@"%d", i);  
  167.     }  
  168. }  
  169. }  
  170.   
  171. @end  
0 0
原创粉丝点击