zoukankan      html  css  js  c++  java
  • 多线程---代码

     

        // NSObject

        // 在子线程中执行代码

        // 参数1: 执行的方法 (最多有一个参数,没有返回值)

        // 参数2: 传递给方法的参数

    //    [self performSelectorInBackground:@selector(cycling:) withObject:@"obj1"];

        

        // 回到主线程更新页面

    //    [self performSelectorOnMainThread:@selector(updateUI:) withObject:nil waitUntilDone:YES];

        

        

        // NSThread

        // 进入子线程

    //    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(cycling:) object:@"thread"];

    //    [thread start]; // 启动线程执行

    //    [thread release];

    //

    //    // 直接启动

    //    [NSThread detachNewThreadSelector:@selector(cycling:) toTarget:self withObject:@"thread2"];

        

        

        // NSOperation

        /*

        // 通常使用NSOperation下的两个子类:NSInvocationOperation、NSBlockOperation

        // NSInvocationOperation

        NSInvocationOperation *invocationOperation = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cycling:) object:@"invocationOperation"] autorelease];

    //    [invocationOperation start]; // 启动任务

        

        // NSBlockOperation

        NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

            for (int i = 0; i < 10000; i++) {

                NSLog(@"blockOperation: %i", i);

            }

        }];

    //    [blockOperation start]; // 启动任务

        

        

        // 创建一个任务队列,NSOperationQueue

        NSOperationQueue *operationQueue = [[NSOperationQueue new] autorelease];

        // 当blockOperation中的任务执行完毕后,invocationOperation才开始执行

    //    [invocationOperation addDependency:blockOperation];

        

        // 设置同时执行任务最大数

        operationQueue.maxConcurrentOperationCount = 1;

        

        // 添加任务到队列中

        [operationQueue addOperation:blockOperation];

        [operationQueue addOperation:invocationOperation];

        */

        

        /**

         *  GCD 分发队列 遵守FIFO原则

         *  串行队列:当一个任务执行完之后,才可以进行下一个任务的执行

         *  并行队列:任务在派发的时候是有顺序的,不用等到上一个任务执行完成之后再执行,同时执行

         */

        

        /**

         *  脱离线程:当线程内部的代码执行完毕之后,线程自动关闭。例如:NSThread / NSObject

         *  非脱离线程:当线程内部的代码执行完毕之后,线程不关闭,等待着下一次的使用。例如:NSOperationQueue

         */

        

        // 1. GCD 使用主队列实现任务的串行,主队列分派的任务,永远在主线程中

        dispatch_queue_t mainQueue = dispatch_get_main_queue();

    //    dispatch_async(mainQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(mainQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(mainQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

        

        

        // 2. 使用自己创建出来的队列,实现任务的串行,新队列执行的任务,在子线程中执行

        // 参数1: 队列的标示

        // 参数2: 类型

        dispatch_queue_t myQueue = dispatch_queue_create("com.lanou3g.lesson_22.myQueue", DISPATCH_QUEUE_SERIAL);

    //    dispatch_async(myQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(myQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(myQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

     

        

        // 3. 使用自己创建的队列,实现任务的并行,执行的任务在不同的子线程中执行

        dispatch_queue_t myQueue2 = dispatch_queue_create("com.lanou3g.lesson_22.myQueue2", DISPATCH_QUEUE_CONCURRENT);

    //    dispatch_async(myQueue2, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(myQueue2, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(myQueue2, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

     

        

        // 4. 使用系统的globle队列,实现任务的并行,在子线程中

        dispatch_queue_t  globleQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //    dispatch_async(globleQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第一个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(globleQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第二个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

    //    dispatch_async(globleQueue, ^{

    //        for (int i = 0; i < 1000; i++) {

    //            NSLog(@"第三个任务:%d %@", i, [NSThread currentThread]);

    //        }

    //    });

     

        // 让代码只执行一次

        for (int i = 0; i < 1000000; i++) {

            static dispatch_once_t onceToken;

            dispatch_once(&onceToken, ^{

                NSLog(@"只执行一次");

            });

        }

        

        // 让一段代码执行多次

        dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t t) {

            NSLog(@"多次执行");

        });

        

        // 让代码延迟几秒执行

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            NSLog(@"延迟5秒执行");

        });

        /**

         *  1. 发送网络请求,获取网络数据的时候需要使用多线程(但是:我们创建网络请求的时候并不需要单独去开启子线程,系统会在方法内部帮我们做这件事)

         *  2. 当有耗时很长的计算的时候,建议使用多线程

         *  3. 当处理数据库中,或者其它位置大量数据的时候使用多线程

         *  4. 总结:将耗时比较长的代码,都放到子线程中运行

         *  5. 重点:页面的刷新必须回到主线程中

         */

    }

     

     

    #pragma mark 循环

    - (void)cycling:(id)obj

    {

        for (int i = 0; i < 10000; i++) {

            NSLog(@"%@: %d", obj, i);

        }

    }

     

    #pragma mark 发送网络图片请求

    - (void)sendRequestForImageWithUrlStr:(NSString *)urlStr

    {

        

        // http://pic.sucaiw.com/up_files/bizhi/a09ba7547e/sucaiw-cdscbj4023.jpg

        // 1. 直接通过NSData获取网络资源数据

        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic.sucaiw.com/up_files/bizhi/a09ba7547e/sucaiw-cdscbj4023.jpg"]];

        

        // 2. 更新图片

        // 参数1: 主线程执行的方法

        // 参数2: 传递给方法的参数

        // 参数3: 是否等待子线程内执行完毕

        [self performSelectorOnMainThread:@selector(updateUI:)

                               withObject:[UIImage imageWithData:data]

                            waitUntilDone:YES];

    }

     

    #pragma mark - 更新页面

    - (void)updateUI:(UIImage *)image

    {

        _imageView.image = image;

    }

     

     

    - (IBAction)buttonAction:(UIButton *)sender

    {

    //    [self sendRequestForImageWithUrlStr:nil];

        

        // 子线程中请求图片

    //    [self performSelectorInBackground:@selector(sendRequestForImageWithUrlStr:) withObject:nil];

        

        

        

        

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            

            

            for (int i = 0; i < 10; i++) {

                NSLog(@"%d", i);

            }

            

        });

        

        

        

        

  • 相关阅读:
    Kafka 入门(四)-- Python Kafka Client 性能测试
    XShell连接阿里云服务器出现”用户密钥加载失败:请确定输入的密码“处理办法
    优化自动化测试流程,使用 flask 开发一个 toy jenkins工具
    我做了回视频,告诉你需要用到哪些工具
    提问的基本原则
    12 月31 日返利系统问题复盘
    外部prometheus监控k8s(k3s)集群
    一个Java类在运行时候,变量是怎么在JVM中分布的呢?
    JVM学习第二篇思考:一个Java代码是怎么运行起来的-下篇
    JVM学习第一篇思考:一个Java代码是怎么运行起来的-上篇
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/4192439.html
Copyright © 2011-2022 走看看