UI进阶——多线程

一、多线程的概念

线程就是指每个独立运行的代码片;
每个赈灾运行的程序(即进程),至少包含一个线程,这个线程为主线程。
只有一个主线程的程序,称为单线程程序。
拥有多个线程的程序,称为多线程程序。
多个线程可以并发执行。
注意:
iOS中关于UI的添加和刷新必须在主线程中操作。

iOS中多线程的种类有四种:
NSThread
NSOperationQueue(是队列,没有开辟线程的能力)
NSObject
GCD

二、NSThread

demo:

-(void)tesr{
    UIImageView* imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1.jpg"]];
    [self.view addSubview:imageView];
    
    
    //轻量级的多线程调用方法,当使用alloc init的方式,需要手动启动,便利构造器的方式不需要手动启动
    //object,是线程回调方法的参数,如果不需要参数,直接赋予值为nil;
    
    NSThread* forThread = [[NSThread alloc]initWithTarget:self selector:@selector(forMethod) object:nil];
    forThread.name = @"我是老二";
    //线程优先级,0到1.0
    forThread.threadPriority = 1.0;
    
    //启动线程
    [forThread start];
    //得到当前线程的信息
    NSLog(@"imageThread---%@",[NSThread currentThread]);
    
    NSMutableArray* array = [NSMutableArray array];
    for (int j = 1; j<11; j++) {
        UIImage * item = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",j]];
        [array addObject:item];
    }
    imageView.animationImages = array;
    imageView.animationDuration = 2.0;
    //    imageView.animationRepeatCount = 10;
    //启动动画
    [imageView startAnimating];

}
//循环一亿次
-(void)forMethod{
    NSLog(@"forThread---%@",[NSThread currentThread]);
    for(int i = 0;i<1000000;i++){
        NSLog(@"%d",i);
    }
}

效果就是可以看到动图的加载并不受循环的影响,这就是线程的意义。

demo:
//nsthread学习
-(void)threadStudy{
    //便利构造器的方式,五返回值
    [NSThread detachNewThreadSelector:@selector(thread_1Action:) toTarget:self withObject:@"thread_1"];
    
    //通过alloc的方式创建
    NSThread *thread_2 = [[NSThread alloc]initWithTarget:self selector:@selector(thread_2Action:) object:@"thread_2"];
    [thread_2 start];
    thread_2.name = @"最优先";
    thread_2.threadPriority = 1.0;
    
    [NSThread detachNewThreadSelector:@selector(thread_3Action:) toTarget:self withObject:@"thread_3"];
}

-(void)thread_1Action:(NSString*)string{
    //当子线程是我们手动开辟的,那么就需要我们自己管理内存
    @autoreleasepool {
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"%@",string);
    }
    
    
}

-(void)thread_2Action:(NSString*)string{
    @autoreleasepool {
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"%@",string);
    }
}

-(void)thread_3Action:(NSString*)string{
    @autoreleasepool {
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"%@",string);
    }
}

记住线程如果是我们自己开辟的,那么即使在mrc模式下,也需要将其放入自动释放池中。

三、NSObject


 //NSObject的多线程方式
//    1.从主线程进入子线程
    [self performSelectorInBackground:@selector(objectAction:) withObject:@"090987开辟子线程的方式"];

在objectAction方法中,写代码并回到主线程:

-(void)objectAction:(NSString*)string{
    NSLog(@"参数%@",string);
    //从子线程中回到主线程
    /**
     *  Description
     *
     *  @param BOOL yes:只有回主线程的回调方法执行结束才执行下面的操作。NO:与之相反
     *
     *  @return 没有返回值
     */
    [self performSelectorOnMainThread:@selector(backMainAction) withObject:nil waitUntilDone:NO];
    NSLog(@"我是在回主线程的底下打印的");
}

四、GCD



demo:
//串行队列,一次只执行一个任务
-(void)serialQueue{
    //创建串行队列
    /**
     *  Description
     *
     *  @param label#> 当前队列的标签 description#>
     *  @param attr#>  字符 description#>
     *
     *  @return 返回一个dispatch_queue_t
     */
    dispatch_queue_t serialQueue = dispatch_queue_create("串行队列",DISPATCH_QUEUE_SERIAL);
    
    //为串行队列添加任务
    dispatch_async(serialQueue, ^{
        NSLog(@"你好------%@",[NSThread currentThread]);
    });
    //异步任务
    dispatch_async_f(serialQueue, "建华会说话了", function);
    dispatch_async(serialQueue, ^{
        NSLog(@"会上学了%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"结婚了%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"被全退了%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"堕落了%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"洗心革面了%@",[NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"出家了%@",[NSThread currentThread]);
    });
    NSLog(@"我在最下面你%@",[NSThread currentThread]);
}

//定义一个回调函数
void function(void* str){
    printf("%s\n",str);
}

//创建并行队列
-(void)concurrentQueue{
    
    //创建并行队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
    //同步任务所处的线程就是当前线程
    
    dispatch_async(concurrentQueue, ^{
        NSLog(@"你好------%@",[NSThread currentThread]);
    });
    //异步任务
    dispatch_async_f(concurrentQueue, "建华会说话了", function);
    dispatch_async(concurrentQueue, ^{
        NSLog(@"会上学了%@",[NSThread currentThread]);
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"结婚了%@",[NSThread currentThread]);
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"被全退了%@",[NSThread currentThread]);
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"堕落了%@",[NSThread currentThread]);
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"洗心革面了%@",[NSThread currentThread]);
    });
    dispatch_async(concurrentQueue, ^{
        NSLog(@"出家了%@",[NSThread currentThread]);
    });
    
}

//系统提供的队列,全局队列
-(void)globalQueue{
    
    //系统提供的一个全局队列
    //参数一,权限,即优先级 2,0 ,-2,INT16_MIN。参数二,系统预留
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //添加任务
    //全局队列是一个系统提供的并行队列
    dispatch_async(globalQueue, ^{
        NSLog(@"*******--------------%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"*******------36736735736737%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"*******-37373756473637635%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"******6666666666666666%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"****555555555555555%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"*******------%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"*******----%@",[NSThread currentThread]);
    });
    dispatch_async(globalQueue, ^{
        NSLog(@"*******%@",[NSThread currentThread]);
    });
    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//gcd常见的使用方式,全局队列和主队列结合使用
-(void)globalAndMainQueue{
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //在全局队列里执行耗时的操作,因为全局队列执行的任务是在子线程中,不会阻塞主线程
        
        dispatch_async(dispatch_get_main_queue(), ^{
            //该block中所执行的任务是在主队列中执行,那么该任务是在主线程中执行,在此处进行刷新UI的行为。
            
        });
    });
}

//gcd中让某些代码执行一次
-(void)onceToken{
    static UIImage* image = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //此处的代码只执行一次
        image = [[UIImage alloc]init];
    });
}

//其他的方法
-(void)otherGCD{
    
    //延时执行的
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"五秒真男人");
    });
    
    //重复执行
    dispatch_apply(3, dispatch_get_global_queue(0,0), ^(size_t size) {
        NSLog(@"五秒再来一次");
    });
    
}


五、队列



demo:
//invocation的回调方法
-(void)invocationAction{
    //打印当前的线程
    
    NSLog(@"%@-------判断是否为主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
}
//operation和operationQueue
-(void)operationQueue{
    
    //初始化一个任务target - action operation并没有开辟线程,将operation在那个线程中使用,operation所在的线程就是当前线程。
    NSInvocationOperation* invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationAction) object:nil];
    //当加入队列的时候,不需要手动启动,在队列则不用手动启动
    [invocation start];
    //操作的block的方式
    NSBlockOperation* blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@------",[NSThread currentThread]);
    }];
    //添加多个block操作,当使用addExecutionBlock为BlockOPeration添加可执行的block的时候,这些可执行的block会在当前线程,或者其他子线程中进行。
    //在启动之前添加事件
    for (int i=0; i<10; i++) {
        [blockOperation addExecutionBlock:^{
            NSLog(@"%@-----%d",[NSThread currentThread],i);
        }];
    };
    blockOperation.completionBlock = ^(){
        NSLog(@"我就是最后一个,你们随便折腾");
    };
        //启动操作
    [blockOperation start];
    NSLog(@"我是在最底下");
}

//queue的学习,队列 nsoperationQuene 是对gcd的一个oc级别的封装。
-(void)operationOperationQuene{
    
    //先初始化队列对象,(其他队列:除了主队列,自己初始化的队列都是其他队列)
    NSOperationQueue *otherQueue = [[NSOperationQueue alloc]init];
    //队列的最大并发数,在同一时刻最多可执行的操作
//    otherQueue.maxConcurrentOperationCount = 1;
    
    //创建可执行的操作对象
    /*for (int i=0; i<10; i++) {
        NSBlockOperation* blockopeartion = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"%@-----%d",[NSThread currentThread],i);
        }];
        //将block操作添加到队列中去
        [otherQueue addOperation:blockopeartion];
    };*/
    NSBlockOperation* blockopeartion_0 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@-----%d",[NSThread currentThread],0);
    }];
    NSBlockOperation* blockopeartion_1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@-----%d",[NSThread currentThread],1);
    }];
    NSBlockOperation* blockopeartion_2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@-----%d",[NSThread currentThread],2);
    }];
    NSBlockOperation* blockopeartion_3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@-----%d",[NSThread currentThread],3);
    }];
    NSBlockOperation* blockopeartion_4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@-----%d",[NSThread currentThread],4);
    }];
    //为时间添加依赖关系,先添加依赖,在添加事件到队列中
    [blockopeartion_4 addDependency:blockopeartion_3];
    
    //当操作对象添加到队列中之后,就不需要手动启动了
    [otherQueue addOperation:blockopeartion_0];
    [otherQueue addOperation:blockopeartion_1];
    [otherQueue addOperation:blockopeartion_2];
    [otherQueue addOperation:blockopeartion_3];
    [otherQueue addOperation:blockopeartion_4];
}

//主队列
-(void)mainQueue{
    
    NSLog(@"%@",[NSThread currentThread]);
    //先创建主队列的对象
    NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
    for (int i = 0 ; i < 10 ; i ++) {
        NSBlockOperation* blockOperation = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"%@-----%d",[NSThread currentThread],i);
        }];
        [mainQueue addOperation:blockOperation];
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值