多线程GCD, NSThread, NSOperation

#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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值