UI23_多线程

来源:互联网 发布:微信图文编辑软件 编辑:程序博客网 时间:2024/06/05 02:39

多线程
引用三方: 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
0 0
原创粉丝点击