IOS2

作者: xiaofengl | 来源:发表于2018-04-02 13:05 被阅读0次

    一、进程和线程:
    什么是进程?


    3.png

    什么是线程?


    4.png

    多线程原理?


    5.png

    二、多线程

    iOS中多线程实现方案:


    2.jpg

    1.pthread 几乎不用,可自行了解
    2.NSThread
    一个NSThread对象就代表一条线程
    创建线程的方式:

    1.创建线程后,启动
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    thread.name = @"设置线程的名字"; // 这里可以设置线程的名字,可用于方便调试等功能
    [thread start]; // 启动线程
    // 线程一启动,就会在线程thread中执行self的run方法
    2.创建线程后自动启动线程
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
    
    3.隐式创建并启动线程
    [self performSelectorInBackground:@selector(run) withObject:nil]; // 这样创建的是子线程
    [self performSelector:@selector(run) withObject:nil]; // 这样创建的是主线程,其实是相当于[self run];这个方法了。
    
    上述2种创建线程方式相对于1的优缺点
    优点:简单快捷
    缺点:无法对线程进行更详细的设置
    

    线程的状态:

    第1行:NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    第2行:[thread start];
    
    6.png

    说明:
    第1行代码执行完后,就会创建一个线程对象,所以内存中,会有一个线程对象,注意,此时还没有放进可调度的线程池,此时线程处于新建状态。

    第2行代码执行,开始线程,一旦开始线程,默认会放进一个可调度的线程池,供线程池来回切换、调度。此时线程处于能运行的状态,就是就绪(Runnable)状态,即能运行状态,能被调度状态,但并不代表已经运行。平常之所以执行start后,就调用我们定义的方法(这里是run),是因为CPU处理非常快,我们感觉不到还有就绪(Runnable)这个过程的而已。

    我们知道,CPU同一时间,只能处理一个线程。之所以有多线程,只不过是CPU快速的来回切换不同的线程,造成的假象而已。
    此时CPU调度了当前线程(橙色背景的线程),此时线程的状态才是运行状态(running),那么假如,CPU调度了其他线程对象(红色背景的线程),那么橙色背景线程又处于就绪状态(Runnable)了。所以线程就处于就绪跟运行状态来回切换了。

    一旦橙色背景线程处于睡眠、同步锁状态时,就是阻塞状态,那么它就会从可调度线程池移除,注意,只是在可调度线程池移除,仍然在内存中的。

    一旦睡眠到到时、得到同步锁,那么线程就会又回到可调度线程池,又处于就绪状态了。

    线程任务执行完毕、异常、强制退出,那么这个线程就会死亡了。

    线程安全:


    1.png

    说明:有2条线程卖票,同时读到还剩1000张票,但是等最后这2条线程执行完毕后,还剩999张票。这样就有问题了。本来应该是998的。

    解决办法:加锁


    3.png

    使用互斥锁的前提:多条线程抢夺同一份资源。

    iOS如何做到线程同步?使用加锁。
    线程同步:多条线程在同一条线上执行(按顺序的执行任务)。
    

    OC在定义属性时有nonatomic和atomic两种选择
    atomic:原子属性,为setter方法加锁(默认就是atomic)
    nonatomic:非原子属性,不会为setter方法加锁

    nonatomic和atomic对比
    atomic:线程安全,需要消耗大量的资源
    nonatomic:非线程安全,适合内存小的移动设备

    iOS开发的建议
    所有属性都声明为nonatomic
    尽量避免多线程抢夺同一块资源
    尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力

    3.GCD
    理解:将任务添加到队列中去执行。

    GCD的队列可以分为2大类型
    并发队列(Concurrent Dispatch Queue)
    可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
    并发功能只有在异步(dispatch_async)函数下才有效
    
    串行队列(Serial Dispatch Queue)
    让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
    

    GCD的使用就2个步骤
    1.定制任务
    确定想做的事情

    2.将任务添加到队列中
    GCD会自动将队列中的任务取出,放到对应的线程中执行
    任务的取出遵循队列的FIFO原则:先进先出,后进后出

    有4个术语比较容易混淆:同步、异步、并发、串行
    同步和异步主要影响:能不能开启新的线程
    同步:在当前线程中执行任务,不具备开启新线程的能力
    异步:在新的线程中执行任务,具备开启新线程的能力
    
    并发和串行主要影响:任务的执行方式
    并发:多个任务并发(同时)执行
    串行:一个任务执行完毕后,再执行下一个任务
    

    GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建
    使用dispatch_get_global_queue函数获得 全局 的 并发 队列

    因此,有4种组合的:
    1.异步并发队列(async)-------最常用
    特点:会创建多条线程
    任务执行方式:并发执行


    image.png

    2.异步串行队列(async)(有时候用)
    特点:会创建子线程,但是只会开一条线程
    任务执行方式:串行执行(一个任务执行完毕后,再执行一个)


    image.png

    3.同步并发队列(sync)
    特点:不会创建子线程
    任务执行方式:串行执行
    并发队列失去了并发功能


    image.png

    4.同步串行队列(sync)
    特点:不会创建线程
    任务执行方式:串行执行

    image.png

    特殊队列--主队列

    5.异步--主队列
    特点:异步功能失效,不会开线程了
    原因:添加到主队列中的任务,都会自动放到主线程中去执行


    image.png

    6.同步--主队列
    特点:会卡死,不能这样使用


    image.png

    如图:


    image.png

    获得串行队列有2中方式:
    1.创建串行队列
    dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); // 创建
    2.使用主队列
    dispatch_queue_t queue = dispatch_get_main_queue();

    各队列的执行效果:


    image.png

    队列组:dispatch_group


    image.png

    4、NSOperation


    image.png image.png image.png

    依赖的使用:


    image.png

    SDWebImage的原理,防止Cell图片下载


    image.png

    SDWebImage的默认缓存时长是多少?---1个星期

    相关文章

      网友评论

          本文标题:IOS2

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