您的位置:首页 > 产品设计 > UI/UE

UI23_多线程

2015-10-19 20:37 337 查看


引用三方: 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: