UI23_多线程
2015-10-19 20:37
369 查看
引用三方: MBProgressHUD, AFNetWorking
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @end
ViewController.m
#import "ViewController.h" #import "MyOperation.h" #import "MBProgressHUD.h" #import "AFNetworking.h" @interface ViewController () @property(nonatomic, retain)UIImageView *imageView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 300, 150, 150)]; [self.view addSubview:self.imageView]; [_imageView release]; self.imageView.backgroundColor = [UIColor orangeColor]; UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; [button addTarget:self action:@selector(GCDAction:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; button.frame = CGRectMake(100, 100, 150, 50); button.backgroundColor = [UIColor lightGrayColor]; [button setTitle:@"测试" forState:UIControlStateNormal]; // // 用AFN进行下载, 用mb显示现在进度, 并且把下载的过程放到queue中进行 // MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; // // 设置标题 // hud.labelText = @"正在下载..."; // // 设置样式 // hud.mode = MBProgressHUDModeDeterminate; // // 建立一个网络请求 // NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://help.adobe.com/archive/en/photoshop/cs6/photoshop_reference.pdf"]]; // // // 用AFN进行下载 // AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; // // NSString *sandBoxPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; // NSString *docPath = [sandBoxPath stringByAppendingPathComponent:@"test.pdf"]; // NSLog(@"%@", docPath); // // // 要把PDF文件下载到指定的路径下 // operation.outputStream = [NSOutputStream outputStreamToFileAtPath:docPath append:NO]; // // 在这个block里能获取到当前的下载进度, hud显示的下载进度就通过这个block进行设置 // [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { // // 下载速度 // NSLog(@"%ld", bytesRead); // // 设置进度 // hud.progress = 1.0 * totalBytesRead / totalBytesExpectedToRead; // // 当下载结束的时候, 相应的应该移除掉在显示进度条的hud, 所以我们要找到关于下载结束的方法, 移除hud // [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { // // 移除hud // [hud removeFromSuperview]; // // } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // // }]; // }]; // // NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // [queue addOperation:operation]; // NSURL *url = [NSURL URLWithString:@"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg"]; // NSData *data = [NSData dataWithContentsOfURL:url]; // UIImage *image = [UIImage imageWithData:data]; // self.imageView.image = image; } - (void)GCDAction:(UIButton *)button { // GCD是苹果提供的一种处理多线程的方法, 在之前iOS使用的是NSThread的类进行线程处理, 4.0之后开始使用GCD, GCD使用比较简单, 但是代码稍微复杂 // 这个方法保证在无论在哪个线程操作, 它只能被执行一次 // static dispatch_once_t onceToken; // dispatch_once(&onceToken, ^{ // // }); // 通过GCD, 创建一个自定义的队列 // 参数1: 给队列起一个名字 // 参数2: 设置并行队列 DISPATCH_QUEUE_CONCURRENT // dispatch_queue_t queue = dispatch_queue_create("liuxiaoju", DISPATCH_QUEUE_CONCURRENT); // dispatch_async(queue, ^{ // // 需要多线程处理的内容, 都写在block里 // NSInteger count = 0; // for (NSInteger i = 0; i < 100000000; i++) { // count++; // } // NSLog(@"%ld", count); // }); // 网络请求一般会在子线程里进行, 但是数据需要在主线程里进行显示, 所以要把子线程请求的数据放到主线程 // 定义一个全局的队列 // 参数1: DISPATCH_QUEUE_PRIORITY_DEFAULT 当前队列优先 // 参数2: 没啥用 dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 找到主线程, 主队列 dispatch_queue_t mainQueue = dispatch_get_main_queue(); // 通过异步的方式进行图片下载 dispatch_async(globalQueue, ^{ // 图片的数据请求 NSURL *url = [NSURL URLWithString:@"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg"]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; // 把子线程的数据, 显示在主线程的控件里 dispatch_async(mainQueue, ^{ self.imageView.image = image; }); }); } - (void)click:(UIButton *)button { // 模拟线程卡死 // 线程卡死就是当前主线程被一个耗时的运算占用, 占用的过程不能对应用进行任何的操作 NSInteger count = 0; for (NSInteger i = 0; i < 30000000000; i++) { count++; NSLog(@"%ld", i); } NSLog(@"%ld", count); } // 多线程第一种: NSObject提供的方法 - (void)NSObjectAction:(UIButton *)button { NSLog(@"a"); [self performSelectorInBackground:@selector(click:) withObject:button]; // 优点: 方法特别简单, 而且是NSObject的方法, 都有这个方法 // 缺点: 对线程没有任何的管理, 没有考虑线程上的安全 } - (void)NSThreadAction:(UIButton *)button { NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(click:) object:nil]; // 这个类主要就是用来管理线程 // 可以给这个线程起一个名 thread.name = @"audrey"; // 找到主线程 // [thread main]; // 让当前的线程休眠几秒之后再执行 // [NSThread sleepForTimeInterval:3]; // NSLog(@"发大水"); // 如果让他去完成线程操作, 必须手动去设置开始 [thread start]; // 优点: 可以快速的创建线程, 而且能对线程进行休眠等操作 // 缺点: 什么都需要自己设置, 比较麻烦, 也没关注线程安全 } // 多线程的第三种: NSOperationQueue - (void)NSOperationAction:(UIButton *)button { MyOperation *operation = [[MyOperation alloc] init]; [operation start]; // 如果只用一个operation的操作的话, 它默认就是在主线程里执行, 所以如果想要实现通过多线程来操作的话, 必须和NSOperationQueue配合来使用 } - (void)queueAction:(UIButton *)button { MyOperation *operation1 = [[MyOperation alloc] init]; MyOperation *operation2 = [[MyOperation alloc] init]; MyOperation *operation3 = [[MyOperation alloc] init]; MyOperation *operation4 = [[MyOperation alloc] init]; MyOperation *operation5 = [[MyOperation alloc] init]; // 创建一个任务的队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 设置最大的并发数 // 并发数就是能同时执行的几个任务 queue.maxConcurrentOperationCount = 2; [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperation:operation3]; [queue addOperation:operation4]; [queue addOperation:operation5]; // 当前应用程序的主线队列, 在异步的时候用过, 目的是为了, 告诉系统子线程的数据传到主线程去显示和使用 // [NSOperationQueue mainQueue]; // 常见的多线程的工具, 优点在于能重复利用闲置的线程, 避免多的重复的创建, 并且内部线程安全进行了保证, 可以设置并发数 // 缺点: 用法比较麻烦 }
Header.h
#ifndef UI23_____Header_h #define UI23_____Header_h // 主要用来放宏 #define HEIGHT 1000 #endif
MyOperation.h
#import <Foundation/Foundation.h> @interface MyOperation : NSOperation @end
MyOperation.m
#import "MyOperation.h" @implementation MyOperation // 在里面需要重写main的方法 - (void)main { // 把卡死线程的操作放在operation的main方法里 NSInteger count = 0; for (NSInteger i = 0; i < 300000000; i++) { count++; // NSLog(@"%ld", i); } NSLog(@"%ld", count); } @end
相关文章推荐
- 从头学Qt Quick(2)-- QML语法从一个简单的例子说起
- UI22_UICollectionView
- UIView
- Quick Sort源码
- UIPopoverController 指向 UIBarButtonItem 并缓慢消失
- UI21_豆瓣数据库
- java关键字之break与continue的区别(简单明了的小例子)
- UI20_数据库
- IOS开发之----让UILabel 垂直方向顶端对齐的代码
- UI19_豆瓣收藏
- iOS UINavigationBar颜色和文字渲染
- UI19_单例
- UIViewController各个方法的加载顺序
- leetcode Unique Paths
- Android Studio 运行时出现 finished with non-zero exit value 2 错误分析
- 解决 Agreeing to the Xcode/iOS license requires admin privileges
- 检查内核反馈uevent消息,并提取出USB插入事件
- Boolean.parseBoolean("true") 和 Boolean.getBoolean("true");的区别及用法
- 手势和UI控件之间冲突的解决方法(比如UITapGesture和UIButton冲突,UIPanGesture和UISlider冲突)
- mvc5 @RenderSection("scripts", required: false) 什么意思