• 多线程与RunLoop


    iOS开发中的多线程

    一个iOS程序,默认开启1条线程--主线程orUI线程
    主线程主要作用:
            显示/刷新UI界面
            处理UI事件(点击、滚动、拖拽事件等)
    主线程使用注意:
            别将耗时操作放在主线程
            
    耗时操作应放在子线程(后台线程or非主线程)

    iOS中多线程实现方案

     
     

    1.pthread -- POSIX Thread    iPhone2.0

    创建子线程:pthread_create
     

    2. NSThread -- 一个NSThread对象代表一条线程

    创建和启动线程
        [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];
        [thread start];
     
    主线程相关方法
        + (NSThread *)mainThread; //获得主线程
        - (BOOL)isMainThread; //判断是否为主线程
        + (BOOL)isMainThread;
     
    其他用法
    其他创建线程方式
        创建线程后自动启动
            [NSThread detachNewThreadSelector:toTarget:withObject:];
        隐式创建线程后自动启动
            [self performSelectorInBackground:withObject:]; // NSObject的方法
     
    线程状态
     阻塞(暂停)线程
      + (void)sleepUntilDate:
      + (void)sleepForTimeInterval:
    强制停止线程
      + (void)exit   //进入死亡状态
      注意:一旦线程停止,就不能再次开启任务
     
    线程同步
        互斥锁 -- 线程同步
        @synchronized(锁对象 eg: self){//加锁
            ....需要锁住的代码
            ....一份代码只能对应一把锁
        }//解锁
     
       
       
    线程间通信
     
       

    3.GCD -- Grand Central Dispatch "牛逼的中枢调度器"

    任务和队列
        队列:用来存放任务
        GCD步骤:定制任务-->将任务添加到队列 (GCD自动取出队列中任务,放到对应线程执行)
        任务的取出遵从:FIFO原则
     
    同步:在当前线程中执行(不具备开启新线程能力)
    异步:在另一条线程中执行
     
    ---------------------------
    全局并发队列:dispatch_get_global_queue
    串行队列:
        1) dispatch_queue_create();   在MRC中调用dispatch_release(queue)
        2) 使用主队列(跟主线程相关联的队列) -- dispatch_get_main_queue
                主队列是GCD自带的特殊串行队列;
                放在主队列中的任务,都会放到主线程中执行
     
    GCD其他用法
     
    只执行一次
        dispatch_once
     
    队列组
        

    4. NSOperation

    1> 基本使用

    NSOperation和NSOperationQueue实现多线程
     
    2>NSOperation(抽象类)子类:
    》NSInvocationOperation
    创建并启动操作对象:
    [[NSInvocationOperation alloc]initWithTarget:selector:object];
    [operation start]; //默认情况下不会创建新线程;除非放到队列中
     
    》NSBlockOperation
    [NSBlockOperation blockOperationWithBlock:];
    [operation start];//默认情况下不会创建新线程;除非放到队列中
     
    [operation addExecutionBlock:];//当operation中的操作个数>1就会开启新线程

    》自定义子类
    必须实现main方法,在main方法中实现具体操作
    - (void)main
    {
        ......
    }
    3> NSOperationQueue
    [[NSOperationQueue alloc]init];
    [queue addOperation:]; //自动执行操作,自动开启线程;默认是并发执行
    [queue addOperationWithBlock:]

    最大并发数设置
    - (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
    一般2-3并发数,5以内
     
    队列的取消、暂停、恢复
    - (void)cancelAllOperations
    - (void)setSuspended:BOOL // YES代表暂停,NO代表恢复

    *设置依赖
    [operationB addDependency:operationA]; // 操作B依赖于操作A
    也可以在不同队列的操作间设置依赖
    注意:不能相互依赖
     
    操作的监听
    operation.completionBlock=^{};
     

    RunLoop

    不能显示的创建管理runloop,每个thread自己就会有一个runloop,在当前线程调用 currentRunLoop方法就能得到线程对应的runloop

    作用

    。使程序一直运行并接收用户输入

    。决定程序在何时处理那些Event

    。调用解耦(--消息队列)

    。节省CPU时间

    RunLoops in Cocoa

    Cocoa中跟RunLoop有关的类

    NSTimer,UIEvent,Autorelease,NSDelayedPerforming,NSThreadPerformAddition

    CADisplayLink,CATransition,CAAnimation,dispatch_get_main_queue(), NSURLConnnection.....

     调用堆栈中

    Xcode调试时调用堆栈中以__CFRunLoopxxxxxx的函数

    RunLoop机制

    》CFRunLoopTimer

    RunLoopTimer的封装

    + (NSTimer *)timerWithTimeInterval: invocation: repeats:

    + (NSTimer *)scheduledTimerWithInterval: invocation: repeats:

    - (void)performSelector: withObject: afterDelay: inModes:

    + (CADisplayLink *)dispalyLinkWithTarget: selector:

    - (void)addToRunLoop: forMode:

    》CFRunLoopSource

    Source是RunLoop的数据源抽象类(protocol)

    RunLoop定义了两个Version的Source:

      1. Source0:处理App内部事件、App自己负责管理(触发)如UIEvent、CFSocket

      2. Source1:由RunLoop和内核管理、Mach port驱动,如CFMachPort,CFMessagePort

    》CFRunLoopObserver

    》CFRunLoopMode

    。RunLoop在同一时间段只能且必须在一种特定Mode下Run

    。更换Mode时,需要停止当前loop,然后重启新loop

    。Mode是iOS App滑动顺畅的关键

    NSDefalutRunLoopMode

      默认状态、空闲状态

    UITrackingRunLoopMode

      滑动ScrollView时

    UIInitializationRunLoopMode

      私有,App启动时

    NSRunLoopCommonModes

      以上一个或几个的组合(可以自己定义组合)

    ScrollView滑动时RunLoopMode的切换:NSDefalutRunLoopMode -开始滑动-> UITrackingRunLoopMode -停止滑动-> NSDefalutRunLoopMode

    》GCD中dispatch到main queue的block被分发到main RunLoop执行,dispatch_after同理

    》RunLoop的挂起和唤醒

    》AFNetworking中创建了一个单例network 线程,用RunLoop让这个线程常驻(不会执行完某次网络操作就杀掉)

    这样子是否只开了一个网络请求子线程?

  • 相关阅读:
    c语言之排序
    c语言中的break 和 continue语句
    c语言之循环
    c语言之选择
    使用函数封装代码
    C语言的运算符
    判断两个对象是否相等:hashcode
    更新线上的资源存在删除和添加的情况-要避免空窗期的实现方法
    变量只能设置一次方法
    JAVA-获取系统信息:内存和系统、PID、内核
  • 原文地址:https://www.cnblogs.com/shanhua/p/4770209.html
Copyright © 2020-2023  润新知