• ios开发之多线程


    多线程的主要是用来执行一些耗时操作,例如网络图片、视频、歌曲、书籍等资源下载,游戏中的音乐播放等,充分发挥多核处理器的优势,并发(同时执行)任务让系统运行的更快、更流畅。

    介绍下比较常用的多线程技术, 主要有NSObject、NSThread、NSOperation、GCD等。

    1、 NSObject多线程技术

     1> 使用performSelectorInBackground可以开启后台线程,执行selector选择器选择的方法

     2> 使用performSelectorOnMainThread可以重新回到主线程执行任务,通常用于后台线程更新界面UI时使用

     3> [NSThread sleepForTimeInterval:1.0f];  让当前线程休眠,通常在程序开发中,用于模拟耗时操作,以便跟踪不同的并发执行情况!

      但是,在程序发布时,千万不要保留此方法!不要把测试中的代码交给客户,否则会造成不好的用户体验。

      提示:使用performSelectorInBackground也可以直接修改UI,但是强烈不建议使用。修改UI最好在主线程中执行

      注意:在使用NSThread或者NSObject的线程方法时,一定要使用自动释放池,否则容易出现内存泄露。

     1 - (void)viewDidLoad
     2 {
     3     [super viewDidLoad];
     4     
     5     // 在后台线程执行方法
     6     [self performSelectorInBackground:@selector(testObject) withObject:nil];
     7     
     8     // 打印当前线程num
     9     NSLog(@"main - %@", [NSThread currentThread]);
    10 }
    11 
    12 - (void)testObject
    13 {
    14     // 自动释放池,避免出现内存泄露
    15     @autoreleasepool {
    16         
    17         // 让当前线程睡眠 2.0 秒
    18         [NSThread sleepForTimeInterval:2.0f];
    19         
    20         // 打印当前线程
    21         NSLog(@"Background - %@", [NSThread currentThread]);
    22     }
    23 }

    2、NSThread多线程技术

    1> 类方法直接开启后台线程,并执行选择器方法

        detachNewThreadSelector

     2> 成员方法,在实例化线程对象之后,需要使用start执行选择器方法

        initWithTarget

      对于NSThread的简单使用,可以用NSObjectperformSelectorInBackground替代

      同时,在NSThread调用的方法中,同样要使用autoreleasepool进行内存管理,否则容易出现内存泄露。

     1 - (void)viewDidLoad
     2 {
     3     [super viewDidLoad];
     4     
     5     // 开启新线程执行方法
     6     [NSThread detachNewThreadSelector:@selector(testObject) toTarget:self withObject:nil];
     7     
     8 //    // 通过实例化一个线程来开启任务
     9 //    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testObject) object:nil];
    10 //    
    11 //    [thread start];
    12     
    13     // 打印当前线程num
    14     NSLog(@"main - %@", [NSThread currentThread]);
    15 }
    16 
    17 - (void)testObject
    18 {
    19     // 自动释放池,避免出现内存泄露
    20     @autoreleasepool {
    21         
    22         // 让当前线程睡眠 2.0 秒
    23         [NSThread sleepForTimeInterval:2.0f];
    24         
    25         // 打印当前线程
    26         NSLog(@"Background - %@", [NSThread currentThread]);
    27     }
    28 }

    3、NSOperation多线程技术

     1> 使用步骤:

        1 实例化操作

            a) NSInvocationOperation

            b) NSBlockOperation

        2 将操作添加到队列NSOperationQueue即可启动多线程执行

      2> 更新UI使用主线程队列

        [NSOpeationQueue mainQueue] addOperation ^{};

     3> 操作队列的setMaxConcurrentOperationCount

        可以设置同时并发的线程数量!

         提示:此功能仅有NSOperation有!

      4> 使用addDependency可以设置任务的执行先后顺序,同时可以跨操作队列指定依赖关系

         提示:在指定依赖关系时,注意不要循环依赖,否则不工作。

     1 @interface FLViewController ()
     2 {
     3     NSOperationQueue *_queue;
     4 }
     5 @end
     6 
     7 @implementation FLViewController
     8 
     9 - (void)viewDidLoad
    10 {
    11     [super viewDidLoad];
    12     
    13     // 1. 初始化操作队列
    14     _queue = [[NSOperationQueue alloc] init];
    15     
    16     // 2. 创建线程操作
    17 //    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(testObject) object:nil];
    18     
    19     NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
    20             
    21             // 让当前线程睡眠 2.0 秒
    22             [NSThread sleepForTimeInterval:2.0f];
    23             
    24             // 打印当前线程
    25             NSLog(@"Background - %@", [NSThread currentThread]);
    26     }];
    27     // 3. 开启线程
    28     [_queue addOperation:op];
    29 }

    4、GCD多线程技术-Grand Central Dispatch

     GCD是基于C语言的框架,该多线程技术是苹果官方推荐使用的。

     1> 要使用GCD,所有的方法都是dispatch开头的

     2> 名词解释

     global  全局

     queue   队列

     async   异步

     sync    同步

     3> 要执行异步的任务,就在全局队列中执行即可

     dispatch_async 异步执行控制不住先后顺序

     4> 关于GCD的队列

     全局队列    dispatch_get_global_queue

     参数:优先级 DISPATCH_QUEUE_PRIORITY_DEFAULT

     始终是 0

     串行队列    dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

     是创建得到的,不能直接获取

     主队列      dispatch_get_main_queue

     5> 异步和同步与方法名无关,与运行所在的队列有关!

     提示:要熟悉队列于同步、异步的运行节奏,一定需要自己编写代码测试!

     规律:并发队列(global/concurrent),根据函数名判断是同步执行(dispatch_sync)还是异步执行(dispatch_async)

        串行队列(serial),无论后面的函数名是同步还是异步,均按照同步执行,并且,如果队列中第一个函数为同步,则该队列中所有的函数均在当前线程(一般为主线程)执行

    /*! dispatch_async(sync)只负责将任务添加至操作队列,并不关心任务什么时候执行
     *  sync: 同步添加,也就说第一个任务A添加完成之后,要等它执行完成,才会添加任务B,然后执行任务B,再添加任务C,执行任务C……
     *  async: 异步添加,任务A添加完成以后,马上添加任务B,然后添加任务C,无论任务是否执行
     *  concurrent: 添加至该队列的任务都是并发的,也就是说,添加进来立刻分配线程执行
     *  serial: 添加至该队列的任务都是顺序执行的,也就是说,在一个线程上按添加顺序执行任务
     */

     同步主要用来控制方法被调用的顺序

     1 - (void)viewDidLoad
     2 {
     3     [super viewDidLoad];
     4     
     5     // 创建一个全局队列,优先级为默认
     6     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     7     
     8     dispatch_async(queue, ^{ // 添加异步任务1-block
     9         NSLog(@"-----1- %@", [NSThread currentThread]);
    10     });
    11     
    12     dispatch_async(queue, ^{ // 添加异步任务2-block
    13         NSLog(@"-----2- %@", [NSThread currentThread]);
    14     });
    15     
    16     dispatch_async(queue, ^{ // 添加异步任务3-block
    17         NSLog(@"-----3- %@", [NSThread currentThread]);
    18     });
    19 }
  • 相关阅读:
    A simple tutorial on SQL Server 2005 Beta 2 Service Broker
    WSSDAL (WSS Data Access Layer) – a SharePoint Web Services alternative
    SQL Server 2005 Beta 2 Service Broker: Create Route
    Enterprise Library: Security Quickstart代码解析篇, Part 1
    Microsoft SQL Server 2005 Beta2初步体验
    Microsoft patterns & practices Enterprise Library系列分析文章
    今天迎来了酷酷的“小黑”- T43
    Windows SharePoint Services Software Development Kit
    Images of Ireland Desktop Theme for Windows XP
    Enterprise Library v1.0 Tutorials
  • 原文地址:https://www.cnblogs.com/liufeng24/p/3500447.html
Copyright © 2020-2023  润新知