iOS学习之路05

来源:互联网 发布:mac 画流程图的软件 编辑:程序博客网 时间:2024/06/05 02:41
  • 基本概念
    • 主线程

      一个iOS程序运行以后,默认会开启一个线程,这个线程就被称为主线程或(UI线程)。主线程的主要作用是显示\刷新UI界面,处理UI事件(点击,滚动,拖拽等)。

    • iOS中的多线程
      • Pthread:基本不使用了
      • NSThread:每个Thread对象对应一个线程,使用较少,线程的生命周期由我们自己管理
      • GCD:基于C语言的框架,可以充分利用多核,苹果推荐使用,生命周期由系统管理
      • NSOperation:基于GCD来实现,对GCD进行了封装,生命周期由系统管理
  • NSThread
    • 创建

      eg:NSThread *thread = [[NSThread alloc] initWithTarget: self selector: @selector(loadImage:) object: @(i)];

    • 常用属性
      • name:进程名称
      • threadProiority:进程的优先级
    • 常用方法
      • + (NSThread *)currentThread;        返回当前进程
      • + (void)sleepForTimeInterval: (NSTimeInterval) ti;        当前进程暂停一个时间戳
      • + (void)exit;        销毁当前进程
      • + (NSThread *)mainThread;        返回主线程
      • - (void)cancel;    取消当前任务
      • - (void)start;        开始当前进程
    • 对NSObject的扩展—同多线程相关
      • performSelectorOnMainThread: ……        使当前实例方法在主线程中执行
      • performSelector: (SEL)aSelector onThread: thr        使aSelector方法在thr线程中执行
      • performSelector: (SEL)aSelector withObject: ……        在新的线程中调用目标selector自动指定线程
  • GCD
    • dispatch_queue_t mainQueue = dispatch_get_main_queue();        获取主队列并赋值给mainQueue变量,主队列:是串行队列
    • dispatch_queue_t globalQueue = dispatch_get_global_queue(0, DISPATCH_QUEU_PRIORITY_DEFAULT);    获取全局队列(并行队列)并赋值

      参数"0":标识符

      参数"DISPATCH_QUEU_PRIORITY_DEFAULT":优先级,这值表示:默认值

      优先级有:

      DISPATCH_QUEU_PRIORITY_HIGH        2

      DISPATCH_QUEU_PRIORITY_DEFAULT        0

      DISPATCH_QUEU_PRIORITY_Low        -2

      DISPATCH_QUEU_PRIORITY_BACKGROUND    INT16_MIN

    • 自定义队列
      • 自定义串行队列

        dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);

        参数" queue1":标识符

        参数"DISPATCH_QUEUE_SERIAL":创建当前队列为串行队列

      • 自定义并行队列

        dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_CONCURRENT);

        参数" queue2":标识符

        参数"DISPATCH_QUEUE_ CONCURRENT":创建当前队列为并行队列

    • 同步提交/同步任务

      dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

    • 异步提交/异步任务

      dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

    • 串/并队列+同/异任务 执行效果
       

      同步任务

      异步任务

      主队列(串行队列)

      同步任务未执行,出现阻塞(阻塞UI更新)

      顺序执行,在主线程中,未开启新线程

      全局队列(并行队列)

      顺序执行,在主线程中,未开启新线程

      同时执行,每个异步任务都开启了新线程

      自定义串行队列

      顺序执行,在主线程中,未开启新线程

      顺序执行,开启一个新线程,所有任务均在这个线程中执行

      自定义并行队列

      顺序执行,在主线程中,未开启新线程

      同时执行,每个异步任务都开启了新线程

      顺序执行(依次执行):先执行完先进去的任务,然后再执行下一个任务

      同时执行(无序执行):多个任务交替执行,因优先级不确定,所以执行顺序凌乱。因CPU执行速度很快,在多个线程中轮流执行多个任务,造成了一种同时执行的假象。

      总结:

      • 先看是什么任务,再看是什么队列,才能决定任务怎么执行
      • 主队列除外,同步/异步任务决定是否开启新线程
      • 串行/并行队列决定任务的执行方式,是顺序执行(开启新的单条线程),还是同时执行(开启新的多条线程)
      • 任何队列的同步任务,都会顺序执行,并且未开启新线程
      • 任何任务的主队列,都不会开启新线程,而在主线程中执行。同步任务(阻塞),异步任务(顺序执行)
      • 常使用任意队列异步任务来执行;更新UI,使用主队列异步任务
  • NSOperation
    • NSOperation(操作类父类,抽象类,不做具体事情)
      • - (void) start;    开始"操作任务"
      • - (void)cancel;    取消"操作任务"
      • - (void)addDependancy: (NSDperation *)op;        添加依赖关系
      • - (void)removeDependency: (NSDeperation *)op;    移除依赖关系
      • 属性queuePriority:"操作任务"在队列中的优先级,在属性maxConcurrentOperationCount为1时,此属性的效果才会体现出来

        NSDperationQueuePriorityVeryLow = -8L        很低

        NSDperationQueuePriorityLow = -4L            低

        NSDperationQueuePriorityNormal = 0        正常

        NSDperationQueuePriorityHeight = 4        高

        NSDperationQueuePriorityVeryHeight        很高

    • NSInvocationOperation(操作类子类,做具体的事情)
      • start方法:在主线程执行,先执行完上一个任务,再执行下一个任务,顺序执行
      • 添加到NSOperationQueue执行队列中,每个任务都被系统放置在没有使用的线程中,同时执行
    • NSBlockOperation(操作类子类,做具体的事情)
      • start方法:在主线程中,顺序执行
      • 添加到NSOperationQueue执行队列中,每个任务都被系统放置在没有使用的线程中,同时执行
      • 实例方法addExeautionBlock添加block任务到操作中每个任务都被系统放置在没有使用的线程中,同时执行
    • NSOperationQueue(操作队列类,存放操作对象)
      • 属性maxConcurrentOperationCount:最大并发数(同一时间执行的任务数)
      • - (void)cancelAllOperations;        取消所有"操作任务"
    • 总结
      • NSInvocationOperation同NSBlockOperation执行效果一样
      • NSInvocationOperation任务是要传入方法,而NSBlockOperation任务则要传入block代码块。NSBlockOperation更实用
    • 问题
      • NSOperationQueue属性suspended设置无效果,不能实现队列的暂停和重新开始
      • NSOperationQueue的cancel方法能够实现取消任务
  • 线程安全

    全局变量、静态变量、属性、公有变量、单例,在被多个线程访问时,会导致线程安全(多线程同时访问变量,会使各个之间的操作的结果出现矛盾)

    解决方案:

        第一种:synchronized同步锁

            例如:synchronized(self){

        //放置操作变量的代码

    }

    第二种:GCD的只执行一次同步锁

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            //放置只执行一次的代码

    })

原创粉丝点击