首页 > 代码库 > 多线程的使用和详解

多线程的使用和详解

多线程有4种

  1. NSObject---NSObject自带的,但是他不能对数据进行保护

  2. NSThread  ---过于复杂,使用起来不够方便

  3. NSOperationQueue  ---操作队列,管理线程,内部有一个线程池,负责对现有的线程进行管理/重用

  4. GDC(grand central dispatch); ----基于C的多线程解决方案

队列有两种(串行/并行)


MainViewController.m


#import "MainViewController.h"
#import "MyOperation.h"
@interface MainViewController ()
@property (nonatomic , retain)UIImageView *imageView;
@end
@implementation MainViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(110, 100, 100, 30)];
    [button setTitle:@"按钮" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor orangeColor];
    button.layer.cornerRadius = 5;
    [self.view addSubview:button];
    [button addTarget:self action:@selector(GCDAction:) forControlEvents:UIControlEventTouchUpInside];
    [button release];
    
    self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 150, 240, 300)];
    self.imageView.backgroundColor = [UIColor cyanColor];
    [self.view addSubview:self.imageView];
    [_imageView release];
    
}
- (void)buttonClick:(UIButton *)button
{
    NSLog(@"判断当前线程是不是主线程%d",[NSThread isMainThread]);
    //让当前的线程休眠3秒
    [NSThread sleepForTimeInterval:3];
    NSLog(@"休眠结束");
    NSLog(@"当前线程: %@",[NSThread currentThread]) ;
    
    int a = 0;
    for (int i = 0 ; i < 600000000; i++) {
        a++;
    }
    NSLog(@"%d",a);
}
- (void)NSObjectAction:(UIButton *)button
{
    //1.多线程的实现方式:NSObject自带的
    //绑定一个方法,然后给他一个参数   优点:简介快速,缺点:不能对数据进行保护
    [self performSelectorInBackground:@selector(buttonClick:) withObject:button];
    
    
}
- (void)threadAciton:(UIButton *)button
{
    //2.NStrread类
    //这个类ude一个对象,就代表一个线程  优点:可以控制线程的所有方面   缺点:太复杂,使用起来不方便
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(buttonClick:) object:button];
    thread.name = @"刘亚芳";
    
    //开始执行子线程
    [thread start];
    [thread release];
}
- (void)operationAction:(UIButton *)button
{
    //NSOperation类
    //本身不能够实现多线程操作,代表一个任务(进程),安排在某个线程里面
    
    MyOperation *opreation = [[MyOperation alloc] init];
    //开始执行任务,执行的任务会在当前执行
    [opreation start];
    [opreation release];
    
//    NSInvocationOperation *op1 = [NSInvocationOperation alloc] initWithTarget:<#(id)#> selector:<#(SEL)#> object:<#(id)#>
    
    
//    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:<#^(void)block#>]
    
}
- (void)poerationQueueAction:(UIButton *)button
{
    //NSOperationQueue 操作队列(管理线程,线程池)  队列有两类:(并行/串行)
    //内部有一个线程池,负责对现有的线程进行管理/重用
    //创建一个新的队列
    
    //主队列是一个串行队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //设置一个最大并发数(如果最大并发数为1,那么就为串行,否则为并行)
    [queue setMaxConcurrentOperationCount:1];
    
    
    //向队列中添加任务
    MyOperation *op1 = [[MyOperation alloc] init];
    MyOperation *op2 = [[MyOperation alloc] init];
    MyOperation *op3 = [[MyOperation alloc] init];
    MyOperation *op4 = [[MyOperation alloc] init];
    
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue addOperation:op4];
    
    [op1 release];
    [op2 release];
    [op3 release];
    [op4 release];
    
}
- (void)GCDAction:(UIButton *)button
{
    //GCD: grand central dispatch 基于C的多线程解决方案
    
    //1.创建一个调度队列
    //参数1: 队列名字   参数2:队列的类型(串行/并行)
    //DISPATCH_QUEUE_CONCURRENT---并行队列
    //DISPATCH_QUEUE_SERIAL ---串行队列
    dispatch_queue_t myQueue = dispatch_queue_create("liuyafang", DISPATCH_QUEUE_SERIAL);
    
    //2.使用的队列
    //参数1:要在哪个队列执行  参数2:要执行的内容
    dispatch_async(myQueue, ^{
        //任务1
        [self buttonClick:button];
    });
    dispatch_async(myQueue, ^{
        //任务2
        NSLog(@"===========");
    });
    
    //使用系统的队列
    //系统提供了5个队列,1个串行队列(主队列),4个并行队列(全局队列)
    
    //获取系统的主队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    dispatch_async(mainQueue, ^{
        //执行在主队列中要做的任务
        
        //全部的UI任务(reloadDate ,给试图赋值)
        
    });
    
    //获取全局队列
    //参数1:获取哪一个全局队列  参数2:给未来使用的(必须填写0)
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    
    //GCD的常见用法
    
    //在全局队列中请求数据
    dispatch_async(globalQueue, ^{
        
        NSString *str = @"http://c.hiphotos.baidu.com/image/pic/item/d50735fae6cd7b8904ac489d0c2442a7d8330eef.jpg";
        NSURL *url = [NSURL URLWithString:str];
        //请求网络地址数据的同步方法
        //因为这个方法在子线程(全局队列)中执行,所以不需要考虑死线程的问题
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        UIImage *image = [UIImage imageWithData:data];
        
        //所有刷新UI的操作都必须回到主队列进行(跳回到子线程)
        dispatch_async(mainQueue, ^{
            self.imageView.image = image;
        });
        
    });
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"乔老爷不该死啊!!!");
    });
    
    
    //一段代码值执行一次,(单列的创建)
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"只执行一次");
    });
    
}
- (void)dealloc
{
    [_imageView release];
    [super dealloc];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/
@end


MyOperation.h

看继承关系---这个是继承与NSOperation

#import <Foundation/Foundation.h>
@interface MyOperation : NSOperation
@end


MyOperation.m

#import "MyOperation.h"
@implementation MyOperation
- (void)main
{
    //自己定义的Operation的类,需要在mian方法中写要执行的任务内容
    
    NSLog(@"当前线程:%@",[NSThread currentThread]);
    
    NSLog(@"是不是主线程尼:%d",[NSThread isMainThread]);
    int a = 0;
    for (int i = 0 ; i < 600000000; i++) {
        a++;
    }
    NSLog(@"%d",a);
}
@end




本文出自 “小刘_Blog” 博客,请务必保留此出处http://liuyafang.blog.51cto.com/8837978/1557452

多线程的使用和详解