美文网首页iOS精选
iOS开发中的四类实现多线程的方法

iOS开发中的四类实现多线程的方法

作者: 不思议的iOS | 来源:发表于2020-07-03 14:33 被阅读0次

    1.pthread 实现多线程操作

    #pragma mark -- pThread
    - (IBAction)pThreadClick:(UIButton *)sender {
        NSLog(@"主线程中进行。。。");
        pthread_t my_pthread;
        pthread_create(&my_pthread, NULL, run, NULL);
    
    }
    void *run(void *data){
        NSLog(@"这里是子线程。。。");
        for (int i = 0; i < 10; i++) {
            NSLog(@"%d",i);
            sleep(1);//模拟延时操作
        }
        return NULL;
    }
    
    

    2.NSThread实现多线程

    #pragma mark -- nsThread
    - (IBAction)nsThreadClick:(UIButton *)sender {
         NSLog(@"主线程中进行。。。");
        //创建方式1
        NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(nsThreadStart) object:nil];
        [thread1 setName:@"threadName_1"];
        [thread1 setThreadPriority:0.4];//优先级 0-1之间
        [thread1 start];
    
        NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(nsThreadStart) object:nil];
        [thread2 setName:@"threadName_2"];
        [thread2 setThreadPriority:0.6];
        [thread2 start];
    
        //创建方式2
    //    [NSThread detachNewThreadSelector:@selector(nsThreadStart) toTarget:self withObject:nil];
    
        //创建方式3
    //    [self performSelectorInBackground:@selector(nsThreadStart) withObject:nil];
    
    }
    -(void)nsThreadStart{
        NSLog(@"这里是子线程。。。的名字是%@",[NSThread currentThread].name);
        for (int i = 0; i < 10; i++) {
            NSLog(@"%d",i);
            sleep(1);
            if (i == 9) {
                //回到主线程刷新UI
                [self performSelectorOnMainThread:@selector(mainRefresh) withObject:nil waitUntilDone:YES];
            }
        }
    }
    -(void)mainRefresh{
        NSLog(@"回到主线程刷新UI");
    }
    
    
    . 线程中枷锁的方式:
            //方式一
            @synchronized (self) {
                //枷锁的代码
            }
    
            //方式二
            NSCondition *diction = [[NSCondition alloc]init];
            [diction lock];
            //枷锁的代码
            [diction unlock];
    
    

    这是我的iOS开发交流群:519832104不管你是小白还是大牛欢迎入驻,可以一起分享经验,讨论技术,共同学习成长!
    另附上一份各好友收集的大厂面试题,需要iOS开发学习资料、面试真题,进群即可自行下载!

    点击此处,立即与iOS大牛交流学习

    3.多线程之GCD讲解

    //GCD的i基本使用
    -(void)gcd1{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [NSThread sleepForTimeInterval:3];
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程刷新UI");
            });
        });
    }
    
    
    //gcd多个任务的使用
    -(void)gcd2{
        /*
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
            NSLog(@"start task 1");
            [NSThread sleepForTimeInterval:1];
            NSLog(@"end task 1");
        });
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
            NSLog(@"start task 2");
            [NSThread sleepForTimeInterval:1];
            NSLog(@"end task 2");
        });
    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"start task 3");
            [NSThread sleepForTimeInterval:1];
            NSLog(@"end task 3");
        });
        */
    
        //加到队列  按任务顺序执行(三个任务在同一个线程)------> 串行队列(dispatch_queue_create第二个参数传NULL)
    //    dispatch_queue_t queue = dispatch_queue_create("com.lql.test.queue", NULL);
    
        //并行队列(dispatch_queue_create第二个参数传 DISPATCH_QUEUE_CONCURRENT)
        dispatch_queue_t queue = dispatch_queue_create("com.lql.test.queue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            NSLog(@"start task 1");
            [NSThread sleepForTimeInterval:1];
            NSLog(@"end task 1");
        });
        dispatch_async(queue, ^{
            NSLog(@"start task 2");
            [NSThread sleepForTimeInterval:1];
            NSLog(@"end task 2");
        });
        dispatch_async(queue, ^{
            NSLog(@"start task 3");
            [NSThread sleepForTimeInterval:1];
            NSLog(@"end task 3");
        });
    
    }
    
    
    模拟两个异步网络请求完成之后在执行别的任务:
    /**
     业务: 模拟两个网络请求,当两个异步的网络请求 都成功之后,再去执行某一件事情
     */
    -(void)gcd3{
        dispatch_queue_t queue = dispatch_queue_create("con.lql.te.queue", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_group_t group = dispatch_group_create();
        //模拟第一个接口开始请求
        dispatch_group_enter(group);
        [self sendRequest1:^{
            NSLog(@"第一个网络请求成功");
            dispatch_group_leave(group);
        }];
         //模拟第二个接口开始请求
        dispatch_group_enter(group);
        [self sendRequest12:^{
            NSLog(@"第一个网络请求成功");
            dispatch_group_leave(group);
        }];
    
        //所有任务处理完成的统一回调
        dispatch_group_notify(group, queue, ^{
            NSLog(@"All task Done");
            //回到主线程
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程刷新UI");
            });
        });
    }
    //模拟第一个 异步网络请求
    -(void)sendRequest1:(void(^)(void))block{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"start task 1");
            [NSThread sleepForTimeInterval:2];
            NSLog(@"end task 1");
            dispatch_async(dispatch_get_main_queue(), ^{
                if (block) {
                    block();
                }
            });
        });
    }
    
    //模拟第二个 异步网络请求
    -(void)sendRequest12:(void(^)(void))block{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"start task 2");
            [NSThread sleepForTimeInterval:2];
            NSLog(@"end task 2");
            dispatch_async(dispatch_get_main_queue(), ^{
                if (block) {
                    block();
                }
            });
        });
    }
    
    
    GCD的其他使用
    -(void)gcd4{
        //gcd单利的使用
        TestSingle *shared = [TestSingle instance];
        NSLog(@"%@",shared);//地址不变
    
        //gcd的延时使用
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"2s之后执行");
        });
    }
    
    

    4.多线程之NSOperation讲解

    使用NSOperation的两种方式:
    • 1.NSInvocationOperation & NSBlockOperation

    • 2.自定义类继承NSOperation

    - (IBAction)nsoperationClick:(UIButton *)sender {
        //方式1
    //    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
        //方式2
        NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"block %d",i);
                [NSThread sleepForTimeInterval:2];
            }
        }];
    
        if (!self.operationQueue) {
            self.operationQueue = [[NSOperationQueue alloc]init];
        }
    //    [operation start];//主线程执行
        [self.operationQueue addOperation:operation];
        NSLog(@"end");
    }
    -(void)test{
        for (int i = 0; i < 3; i++) {
            NSLog(@"invocation %d",i);
            [NSThread sleepForTimeInterval:2];
        }
    }
    
    

    自定义NSOperation

    1.自定义MyOperation类

    #import "MyOperation.h"
    @interface MyOperation()
    @property(nonatomic,copy)NSString *operName;
    @property BOOL isOver;
    @end
    @implementation MyOperation
    -(instancetype)initWithName:(NSString *)name{
        if (self = [super init]) {
            self.operName = name;
        }
        return  self;
    }
    -(void)main{
        //模拟网络请求
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [NSThread sleepForTimeInterval:2];
            if (self.cancelled) {
                return ;
            }
            NSLog(@"%@,继续执行操作",self.operName);
            self.isOver = YES;
        });
    
        while (!self.isOver && !self.cancelled) {
            [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
    
    }
    @end
    
    

    2.使用

    - (IBAction)nsoperationClick:(UIButton *)sender {
        //方式1
    //    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
        //方式2
        NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
            for (int i = 0; i < 3; i++) {
                NSLog(@"block %d",i);
                [NSThread sleepForTimeInterval:2];
            }
        }];
    
        if (!self.operationQueue) {
            self.operationQueue = [[NSOperationQueue alloc]init];
        }
    
        [self.operationQueue setMaxConcurrentOperationCount:2];//设置线程个数
    
    ////    [operation start];//主线程执行
        [self.operationQueue addOperation:operation];
    
        MyOperation *myopertionA = [[MyOperation alloc]initWithName:@"myopA"];
        MyOperation *myopertionB = [[MyOperation alloc]initWithName:@"myopB"];
        MyOperation *myopertionC = [[MyOperation alloc]initWithName:@"myopC"];
        MyOperation *myopertionD = [[MyOperation alloc]initWithName:@"myopD"];
    
        //添加依赖  B->C->A->D
        [myopertionD addDependency:myopertionA];//D依赖A
        [myopertionA addDependency:myopertionC];//A依赖C
        [myopertionC addDependency:myopertionB];//C依赖B
    
        [self.operationQueue addOperation:myopertionA];
        [self.operationQueue addOperation:myopertionB];
        [self.operationQueue addOperation:myopertionC];
        [self.operationQueue addOperation:myopertionD];
         NSLog(@"end");
    }
    -(void)test{
        for (int i = 0; i < 3; i++) {
            NSLog(@"invocation %d",i);
            [NSThread sleepForTimeInterval:2];
        }
    }
    

    查看更多: iOS面试题合集

    欢迎加入我的iOS讨论群:519832104 获取大厂面试资料。
    结识人脉、讨论技术, 你想要的这里都有!抢先入群,跑赢同龄人!

    相关文章

      网友评论

        本文标题:iOS开发中的四类实现多线程的方法

        本文链接:https://www.haomeiwen.com/subject/zdssqktx.html