• 多线程3


    //

    //  ViewController.m

    //  UI-NO.24多线程-1

    //

    //  Created by Bruce on 15/8/25.

    //  Copyright (c) 2015年 Bruce. All rights reserved.

    //

    /*

     当用户下载资源、进行图像处理、耗时数据处理等任务时 往往希望操作这个任务的时候 其他的操作不会被中断 这时候 就用到了 多线程

     

     

     在单线程中一个线程只能执行一个任务,一个任务处理不完另一个任务就不能开始,这样会影响用户体验 让用户感觉APP卡顿

     

     

     现在苹果手机都是多核处理器,这样我们可以把一个任务分成多个步骤,在不要求顺序的情况下 使用多线程既能解决线程阻塞 增加用户体验又能充分利用多核处理器运行能力

     

     

     

     每个应程序的内部,存在一个或多个执行线程,它同时或在一个几乎同时执行不同的操作

     

     

     面试题:什么是进程?什么是线程?什么是多线程?

     进程与线程:每个系统运行的程序都是一个进程,每个进程里面包含了一到多个线程

     

     线程是一组指令的集合,程序中一个单一的顺序控制流程,是一个程序中,独立运行的程序片段(一个应用程序里面 单一的顺序控制执行的一个任务)

     

     

     程序运行后,系统会创建一个叫做(main)主线程的线程,所有的UI控件都必须运行在主线程中,所以有人也叫它UI线程

     

     

     如果将所有的任务都放在主线程中,容易造成UI阻塞

     

     

     多线程:在同一个应用程序内,同时运行多个线程,完成不同的工作,叫做多线程

     

     

     为什么要使用多线程:单线程的应用程序中,代码沿直线执行,只有前面的代码执行完了,才会去执行后面的代码,中间这段时间,实际上就处于等待状态。当用户执行某项操作,比如上传文件,或者下载文件,主线程会执行这个任务,直到上传结束后,主线程才能继续后面的工作,在这短时间内,主线程处于忙碌状态,不会对用户的请求做出任何反应,最直观的感受就是界面卡死,特别是操作这个任务需要大量的时间的时候就更为明显

     既然单一的一个线程不能满足我们的需求,那我们就可以使用今天要讲的多线程进行操作,在用户需要上传或者下载文件的时候,开辟一个独立的线程,专门负责这个任务,这样两个线程就会并行去工作,主线程也就不用花费这么久去等待去更新界面了

     当然,使用多线程有利有弊,多线程高效的背后是代码复杂程度的上升,需要管理线程之间的同步和互斥,需要协调线程间的通信,这就是我们常说的线程管理

     

     

     在iOS中每个进程启动后都会建立一个主线程(UI线程),在iOS中除了主线程,其他子线程是独立于Cocoa Touch的

     

     

     // iOS中有几种多线程方式

     iOS中有三种多线程策略供开发者使用:NSThread、NSOperation(基类不可以直接使用  只能使用他的子类)、GCD(Grand Central Dispatch)

    //  GCD 苹果 推荐的一种 实现 多线程的方式

     

     

     

     // 轻量级 :对系统框架的依赖性的程度

     NSThread:是这三种策略里面相对轻量级的,需要自己去管理他的生命周期,以及线程之间的同步,线程共享同一应用程序的部分内存空间,他们拥有对数据相同的访问权限,所以得协调多个线程对同一数据的访问,常用的做法是在访问之前加锁,这会导致一定的性能开销

     

     

     NSThread的创建和启动:

     NSThread的创建主要有两种直接方式:

     init

     这种方式得手动去启动线程,虽然我们alloc init了 但是只有我们start的时候才会真正去创建去启动这个线程(这是一种延迟实现的思想)

     

     + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

     这种创建线程的方式,会立即开辟一个线程并启动线程

     

     

     线程之间的通讯

     performSelectorOnMainThread withObject:waitUntilDone:

     更新主线程

     performSelector:onThread:withObject:waitUntilDone:

     更新指定子线程

     

     

     解决 阻塞 主线程

     */

    #import "ViewController.h"

     

    @interface ViewController ()

    {

        UIImageView *pointView;

        

        NSThread *newThread;

        NSCondition *condition;

        int ticketNum;

        int count;

    }

    @end

     

    @implementation ViewController

     

    - (void)viewDidLoad {

        [super viewDidLoad];

        

        /*

         [NSThread detachNewThreadSelector:@selector(updata) toTarget:self withObject:nil];

         //    这种创建线程的方式,会立即开辟一个线程并启动线程

         NSLog(@"主线程");

         */

        

        /*

         newThread = [[NSThread alloc]initWithTarget:self selector:@selector(updata1) object:nil];

         [newThread start];

         NSLog(@"主线程");

         //    这种方式得手动去启动线程,虽然我们alloc init了 但是只有我们start的时候才会真正去创建去启动这个线程(这是一种延迟实现的思想)

         

         */

        /*

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

         NSLog(@"主线程");

         //    这是一种隐式创建线程的方法,效果与第一种一样

         */

        

        /*

         线程之间的通讯

         

         performSelectorOnMainThread withObject:waitUntilDone:

         更新主线程

         

         performSelector:onThread:withObject:waitUntilDone:

         更新指定子线程

         */

        

        //    线程同步  线程锁

        //    NSCondition

        /*

        ticketNum = 100;

        condition = [[NSCondition alloc]init];

        

        NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(act) object:nil];

        thread1.name = @"thread1";

        [thread1 start];

        

        NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(act) object:nil];

        thread2.name = @"thread2";

        [thread2 start];

        

        NSThread *thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(act) object:nil];

        thread3.name = @"thread3";

        [thread3 start];

    */

        

        

        

        

        

    //    ---------------------------------------------

        

        self.view.backgroundColor = [UIColor blackColor];

        

        pointView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];

        pointView.backgroundColor = [UIColor whiteColor];

        pointView.layer.cornerRadius = 50;

        pointView.layer.masksToBounds = YES;

        [self.view addSubview:pointView];

        

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];

        [self.view addGestureRecognizer:tap];

        

        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

        button.frame = CGRectMake(10, 20, 100, 30);

        [button setTitle:@"下载图片" forState:UIControlStateNormal];

        [button addTarget:self action:@selector(loadData) forControlEvents:UIControlEventTouchUpInside];

        [self.view addSubview:button];

        

    }

    /*

    - (void)act

    {

        NSLog(@"%@",[NSThread currentThread]);

        while (ticketNum >= 0) {

            

            [condition lock];

            if(ticketNum >= 0){

                [NSThread sleepForTimeInterval:0.1];

                count = 100 - ticketNum;

                NSLog(@"当前票数是:%d,售出:%d,线程名:%@",ticketNum,count,[NSThread currentThread].name);

                ticketNum--;

            }

            [condition unlock];

            

        }

    }

    - (void)updata

    {

        sleep(10);

        NSLog(@"子线程");

    }

     

    - (void)updata1

    {

        sleep(5);

        NSLog(@"newThread子线程");

        [self performSelector:@selector(yayaya) onThread:newThread withObject:nil waitUntilDone:YES];

    }

    - (void)yayaya

    {

        NSLog(@"执行");

    }

    */

    //普通

    - (void)loadData

    {

        NSLog(@"...");

        sleep(3);

        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://file.bmob.cn/M01/33/41/oYYBAFXcMhaARlGBAABOZfJ7P6Y062.png"]];

        pointView.image = [UIImage imageWithData:data];

    }

     

    /*

    //多线程

    - (void)loadData

    {

        NSLog(@"...");

        

        [NSThread detachNewThreadSelector:@selector(commentData) toTarget:self withObject:nil];

        

    }

     

    - (void)commentData

    {

        sleep(3);

        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://file.bmob.cn/M01/33/41/oYYBAFXcMhaARlGBAABOZfJ7P6Y062.png"]];

        pointView.image = [UIImage imageWithData:data];

    }

    */

     

    - (void)tap:(UITapGestureRecognizer *)sender

    {

        

        pointView.center = [sender locationInView:self.view];

    }

     

     

     

     

    - (void)didReceiveMemoryWarning {

        [super didReceiveMemoryWarning];

        // Dispose of any resources that can be recreated.

    }

     

    @end

     

  • 相关阅读:
    员工管理系统————员工删除模块
    员工管理系统————员工管理模块
    员工管理系统————登陆验证模块
    员工管理系统————首页登陆模块
    为什么大多数编程语言中的数组都从0开始
    C/C++大数库简介
    一个比较全面的java随机数据生成工具包
    Linux环境下JDK/Eclipse一键安装脚本
    OOAD与UML笔记
    Cache模拟器(CacheSim)
  • 原文地址:https://www.cnblogs.com/wukun16/p/4884142.html
Copyright © 2020-2023  润新知