#import "ViewController.h"
#import "MyOperation.h"
#import "MBProgressHUD.h"
#import "AFNetworking.h"
@interface ViewController ()
@property(nonatomic, retain)UIImageView *imageView;
@end
@implementation ViewController
- (void)dealloc {
[_imageView release];
[super dealloc];
}
- (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.imageView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:self.imageView];
[_imageView release];
NSString *strURL = @"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg";
NSURL *url = [NSURL URLWithString:strURL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
self.imageView.image = image;
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(100, 100, 150, 50);
[self.view addSubview:button];
[button setTitle:@"测试" forState:UIControlStateNormal];
button.backgroundColor = [UIColor cyanColor];
[button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
#pragma mark 以下是关于AFN下载的内容
// 用AFN(AFNetworking)进行下载, 用MBP(MBProgressHUD)显示现在进度, 并且把下载的过程放到Queue中进行
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
// 设置标题
hud.labelText = @"正在下载...";
// 设置样式
hud.mode = MBProgressHUDModeDeterminateHorizontalBar;
// 建立一个网络请求
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) {
// 设置进度
hud.progress = 1.0 * totalBytesRead / totalBytesExpectedToRead;
// 下载速度
NSLog(@"%ld", bytesRead);
}];
// 当下载结束的时候, 相应的应该移除掉在显示进度的hud, 所有我们要找到关于下载结束的方法, 移除hud
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// 移除hud
[hud removeFromSuperview];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
}
- (void)click:(UIButton *)button {
// 模拟线程卡死
// 线程卡死就是当前线程被一个耗时的运算占用, 占用的过程不能对应用进行任何的操作
NSInteger count = 0;
for (NSInteger i = 0; i < 60000000; i++) {
count++;
NSLog(@"%ld", i);
}
NSLog(@"%ld", count);
}
// 多线程第一种: NSObject提供的方法
- (void)NSObjectAction:(UIButton *)button {
NSLog(@"1");
[self performSelectorInBackground:@selector(click:) withObject:button];
// 优点: 方法特别简单, 而且是NSObject的方法, 都有这个方法
// 缺点: 对线程么有任何的管理, 没有考虑线程上的安全
}
- (void)NSThreadAction:(UIButton *)button {
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(click:) object:nil];
// 这个类主要就是用来管理线程
// 可以给这个线程其一个名
thread.name = @"laohan";
// 找到主线程
[thread main];
// 让当前的线程休眠几秒后再执行
// [NSThread sleepForTimeInterval:10];
// NSLog(@"fdfadfa");
// 如果让他去完成线程操作, 必须手动设置开始
[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];
// 常见的多线程的工具, 优点在于能重复利用闲置的线程, 避免多的重复的创建, 并且内部对线程安全进行了保证, 可以设置并发数
// 缺点: 用法比较麻烦
}
- (void)GCDAction:(UIButton *)button {
// GCD 是苹果提供的一种处理多线程的方法, 在之前iOS使用的是NSThread的类型进行多线程处理, 4.0之后开始使用GCD, GCD使用比较简单, 但是代码稍微复杂
// 在创建单例的时候使用过GCD创建单例对象
// 这个方法保证无论在哪个线程操作, 它只能被执行一次
// static dispatch_once_t onceToken;
// dispatch_once(&onceToken, ^{
//
// });
#pragma mark 以下是GCD创建的队列
// // 通过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 < 6000000; i++) {
// count++;
// }
// NSLog(@"%ld", count);
// });
#pragma mark 网络请求一般会在子线程里进行, 但是数据需要在主线程里进行显示, 所以要把子线程请求的数据放到主线程
// 参数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, ^{
NSString *strURL = @"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg";
NSURL *url = [NSURL URLWithString:strURL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 把子线程的数据, 显示在主线程的控件里
dispatch_async(mainQueue, ^{
self.imageView.image = image;
});
});
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
多线程GCD, NSThread, NSOperation
最新推荐文章于 2023-05-10 20:15:33 发布