UI多线程

来源:互联网 发布:有个淘宝的软件是什么 编辑:程序博客网 时间:2024/04/27 01:53

        一个应用程序就相当于一个进程, 在这个进程中包含了很多的线程.

        在ios中, 打开一个应用程序, 系统就会给我们创建一个线程, 我们称之为主线程, 其他的就是子线程. 主线程主要管理UI界面, 子线程负责处理数据.

        多线程实现的几种方式:

// 1.NSObject的多线程实现方式- (void)NSObjectThread:(UIButton *)button{    // 最简单的多线程的执行方式    // 参数1: 需要在后台执行的(子线程)方法    // 参数2: 给这个方法传参    [self performSelectorInBackground:@selector(buttonAction:) withObject:nil];}// 2.NSThread实现多线程操作- (void)NSThreadAction:(UIButton *)button{    // NSThread 的一个对象 就代表一个线程        // 创建一个NSThread对象 就创建了一个子线程    // 优点: 在所有的多线程的实现方法中,最轻量级    // 优点2: 可以按照要求 任意控制thread对象(控制线程本身)    // 缺点: 控制起来太过繁琐, 不能自己控制线程安全    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(buttonAction:) object:nil];        // 启动线程 执行内部方法    [thread start];}// 3.NSOperation实现多线程操作- (void)NSOperationAction:(UIButton *)button{    // NSOperation代表一个任务 自己不能实现多线程    // NSOperation是一个抽象类 本身不能直接使用 需要创建一个子类去编写实现的内容    MyOperation *operation = [[MyOperation alloc] init];        // 启动线程 执行内部方法    // 任务开始 会在当前线程执行任务(main 方法中得代码)    [operation start];    [operation release];        // 系统已经写好的两个类 可以直接使用    // 1//    NSInvocationOperation *inOperation = [[NSInvocationOperation alloc] initWithTarget:(id) selector:(SEL) object:(id)];        // 2//    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{//        // 这里填写 要执行的任务内容//        //    }];    }// 4.NSOperationQueue 队列- (void)queueAction:(UIButton *)button{    // 任务队列(NSOperationQueue) 内部管理一系列的线程    MyOperation *op1 = [[MyOperation alloc] init];    MyOperation *op2 = [[MyOperation alloc] init];    MyOperation *op3 = [[MyOperation alloc] init];    MyOperation *op4 = [[MyOperation alloc] init];        // 创建一个队列    NSOperationQueue *queue = [[NSOperationQueue alloc] init];        // 设置最大并发数    [queue setMaxConcurrentOperationCount:2];        // 将任务添加到队列中    [queue addOperation:op1];    [queue addOperation:op2];    [queue addOperation:op3];    [queue addOperation:op4];        // 优点: 1.能够自己管理 线程安全  2.能够合理的安排线程  3.降低系统的开销  4.提高对线程的利用率    // 缺点: 1.可读性比较差  2.写起来比较繁琐   3.重量级}//*** 5.Grand Central Dispatch (GCD) 大调度中心- (void)GCDAction:(UIButton *)button{    // GCD 是基于队列的 多线程实现方式    // 队列的类型    // 1. 并行(Concurrent): 多个任务可同时执行    // 2. 串行(Serial):     多个任务依次执行(同一时间只能执行一个任务)        // 自己创建一个队列    // 参数1: 给队列起一个名字(随意取)    // 参数2: 选择队列的类型    //       *并行队列 DISPATH_QUEUE_CONCURRENT    //       *串行并列 DISPATH_QUEUE_SERIAL    dispatch_queue_t queue = dispatch_queue_create("zhao", DISPATCH_QUEUE_CONCURRENT);        // 使用队列    // 参数1: 在哪个队列中执行代码    // 参数2: 要执行的代码    dispatch_async(queue, ^{        [self buttonAction:nil];    });}// 6.GCD 定义的 系统队列- (void)GCDSystem:(UIButton *)button{    // 系统定义了5个队列        // 1. 一个串行队列 主队列 作用: 管理主线程的相关事务        // 获得主队列    dispatch_queue_t mainQueue = dispatch_get_main_queue();// 系统给的宏////    // 在主队列执行任务//    dispatch_async(mainQueue, ^{//        [self buttonAction:nil];//    });        // 2. 四个并行队列 (全局队列)        // 获得全局队列    // 参数1: 选择队列的优先级    // 参数2: 给未来使用的 一般填0    dispatch_queue_t globe = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//    dispatch_async(globe, ^{//        [self buttonAction:nil];//    });//    //    dispatch_async(globe, ^{//        [self buttonAction:nil];//    });        //***** GCD高端使用方法    //1. 全局队列获取数据 回到主队列 将数据加载到视图上//     dispatch_async(globe, ^{//         //         // 全局队列(子线程)获取数据//         NSString *str = @"http://www.baidu.com";//         NSURL *url = [NSURL URLWithString:str];//         //         // 同步方法获取数据//         NSData *data = [NSData dataWithContentsOfURL:url];//         UIImage *image = [UIImage imageWithData:data];//         //         // 返回主线程 加载UI/更新UI//         dispatch_async(mainQueue, ^{//             UIImageView *imageView = [[UIImageView alloc] init];//             //             // 给视图赋值//             [imageView setImage:image];//         });//     });        //2. 一段代码只执行一次        // 大部分时候都在单例方法里面使用    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        NSLog(@"只执行一次");    });        //3. 一段代码重复执行多次(全局队列有效)        // 参数1: 要执行多少次    // 参数2: 在哪个队列执行    // 参数3: 要执行的内容    dispatch_apply(4, globe, ^(size_t a) {        NSLog(@"%zu", a);    });        //4. 定时    // 参数1: 间隔时间(秒)    // 参数2: 执行内容    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        NSLog(@"====");    });}

      buttonAction:

- (void)buttonAction:(UIButton *)button{    // 模拟主线程堵塞状态    int count = 0;    for (int i = 0; i < 600000000; i ++) {        count ++;    }    NSLog(@"%d", count);        // 判断 当前任务是否为主线程    BOOL b = [NSThread isMainThread];    NSLog(@"是否为主线程: %d", b);// 0 不是  1 是        // 获取到当前的线程    NSThread *thread = [NSThread currentThread];    NSLog(@"当前的线程: %@", thread);// 主线程是1}

      MyOperation.m

- (void)main{    // operation 在 main 方法中写 要执行的任务    int count = 0;    for (int i = 0; i < 600000000; i ++) {        count += 1;    }    NSLog(@"%d", count);        // 判断 当前任务是否为主线程    BOOL b = [NSThread isMainThread];    NSLog(@"是否为主线程: %d", b);// 0 不是  1 是        // 获取到当前的线程    NSThread *thread = [NSThread currentThread];    NSLog(@"当前的线程: %@", thread);// 主线程是1    }



0 0