iOS开发——多线程

很多朋友都说iOS开发中,最难理解和学习的就是多线程,很多的原理实现都是通过log看到,也比较抽象,本人也是在多线程方面投入过很多脑细胞。。无论这方面的知识掌握和应用起来是否轻松,牢固的基本功、正确的认识理解、再加上充分的实战经验,都能助你将其搞定。这里先介绍一些多线程的知识以及应用,作为讨论,大家共同学习。

一、多线程基本概念

1、线程与进程 

(1)进程:操作系统的每一个应用程序就是一个进程

(2)线程:进程的基本执行单元,一个进程的所有任务都在线程中执行

2、主线程

(1)定义:一个程序运行后,默认会开启1个线程,称为“主线程”或“UI线程”。其他为“子线程”。

(2)作用及注意:线程一般用来 刷新UI界面 ,处理UI事件(比如:点击、滚动、拖拽等事件),避免将耗时的操作放到主线程,以免造成主线程卡顿。

3、多线程原理

(1)是CPU快速的在多个线程之间的切换(自身的随机调度算法)。

(2)同步/异步:

  • 同步:指的就是在当前线程(不一定是主线程)中,从上而下依次执行任务(代码块的阅读顺序),这个就叫做同步。
  • 异步:指不在当前线程中执行了,开辟新的线程执行, 注意:即使在别的线程中执行,也是从上而下依次执行的。

4、iOS多线程实现方案

5、线程的占用空间:

(1)子线程:512KB。

(2)主线程:512KB。这里官方文档给出的是1M,实际测试为512,可以打印线程的stackSize属性验证。

6、线程的状态和生命周期:

(1)控制线程的状态(以NSThread管理线程为例)

  a、启动线程:- (void)start;

   线程进入就绪状态,当线程执行完毕后自动进入死亡状态。

  b、暂停(阻塞)线程

    + (void)sleepUntilDate:(NSDate *)date;

    + (void)sleepForTimeInterval:(NSTimeInterval)ti;

    线程进入阻塞状态

  c、停止线程

    + (void)exit;

    线程进入死亡状态

(2)状态图

7、线程的属性(以NSThread管理线程为例,一下是NSTread类中的方法或属性)

(1)stackSize:占内存大小

(2)name:名字

(3)threadPriority:优先级(不推荐使用)

(4)  qualityOfService:服务质量

二、多线程深入理解

1、线程间资源共享/抢夺

(1)定义:一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,当多个线程访问同一块资源时,各个线程提取和修改数据不同步,很容易引发数据错乱和数据安全问题。

(2)互斥锁(线程同步) :解决上面的问题

  • 代码:@synchronized(锁对象) {  需要锁定的代码  }
  • 每一个对象(NSObject)内部都有一个锁(变量),当有线程要进入synchronized到代码块中会先检查对象的锁是打开还是关闭状态,默认锁是打开状态(1),如果是线程执行到代码块内部 会先上锁(0)。如果锁被关闭,再有线程要执行代码块就先等待,直到锁打开才可以进入。
  • 互斥锁的实现流程

   线程执行到synchronized

    i.   检查锁状态 如果是开锁状态转到ii  ,如果上锁转到v

    ii.   上锁(0)

    iii.      执行代码块

    iv.    执行完毕 开锁(1)

    v.       线程等待(就绪状态)

  • 注意:必须使用全局对象来提供“锁”,否则同样锁不住。

2、原子属性

(1)属性中的修饰符

  • nonatomic :非原子属性
  • atomic  : 原子属性,针对多线程设计的,是默认值。保证同一时间只有一个线程能够写入,但是同一个时间多个线程都可以取值。
  • 自旋锁:atomic  本身就有一把锁(自旋锁),保证“单写多读”:单个线程写入,多个线程可以读取。如果发现有其它线程正在锁定代码,线程会用死循环的方式,一直等待锁定的代码执行完成 。自旋锁更适合执行不耗时的代码。
  • iOS开发的建议:
    • 所有属性都声明为nonatomic,移动设备内存小,atomic虽然相对线程安全,但是消耗资源较多。
    • 尽量避免多线程抢夺同一块资源(多个线程访问和修改同一数据)。
    • 尽量将加锁、资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力。

3、线程安全

(1)多个线程同时操作一个全局变量是不安全的,使用自旋锁并不是绝对的安全(因为单写多读)。

(2)线程安全:在多个线程进行读写操作时,仍然能够保证数据的正确 。使用互斥锁可以实现,但是消耗性能。

(3)关于主线程(UI线程):几乎所有UIKit??提供的类都是线程不安全的,所有更新UI的操作都在主线程上执行。

4、NSRunLoop

(1)功能作用:运行循环,又叫消息循环或事件循环。

  • 检测、接收  “输入事件”  并执行。
  • 保证程序不退出(主线程)。
  • 如果没有事件发生,会让程序进入休眠状态。

(2)特点:

  • NSRunLoop不能单独存在,必须存在于线程中,不论主线程中还是子线程中都有一个消息循环。
  • 主线程的RunLoop是默认开启的,子线程中的RunLoop默认不开启(使用run方法开启)。
  • 只要线程一启动,内部就会有一个默认的主RunLoop,而每一个App,只要一启动,就会自动有一个主线程。

(3)(两大核心之一)输入事件

  • 输入源:比如 键盘输入,滚动scrollView,performSelector方法
  • 定时源:NSTimer 定时器

(4)(两大核心之二)运行模式(消息循环模式):

  • 线程的消息循环运行在某一种消息循环模式上。
  • 输入事件必须设置消息循环的运行模式,并且如果想让输入事件可以在消息循环上执行,输入事件的消息循环运行模式必须和当前消息循环的运行模式一致
  • 两种常用的运行模式:NSDefaultRunLoopMode、NSRunLoopCommonModes。
  • 实例:输入事件是定时源
 //定时源 (计时器)
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(demo) userInfo:nil repeats:YES];
        /*
        参数1:输入源
        参数2:输入源的模式,要和当前消息循环的模式对应,才可以让消息循环执行输入源
        NSDefaultRunLoopMode默认模式 NSRunLoopCommonModes包含了很多种模式
    */
    [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSRunLoopCommonModes];

5、自动释放池

(1)主线程自动释放池的创建和销毁:

  • 每一次主线程的消息循环开始的时候会先创建自动释放池。
  • 消息循环结束前,会释放自动释放池。
  • 自动释放池被销毁或耗尽时会向池中所有对象发送 release 消息,释放所有 autorelease 的对象(引用计数-1)。
  • 自动释放池随着消息循环的开始和结束不断的重建和销毁。

(2)子线程的自动释放池:

  • 在子线程开启时手动创建释放池。因为主线程可以自动生成释放池,而子线程不可以。为了保证消息循环结束(线程结束)时,所有的对象可以正常入池和释放,必须手动添加。
  • 其他情况和主线程相同。

(3)什么时候使用自动释放池:(官方文档建议)

  • 开启子线程时。
  • 在一个循环中,生成了大量的临时变量,需要手动在循环内部加入释放池(否则内存会爆。。)。
  • 例如:
for (int i = 0; i < largeNumber; ++i) {
     @autoreleasepool {
        NSString *str = @"Hello World";
            str = [str stringByAppendingFormat:@" - %d", i];
            str = [str uppercaseString];

        }
    }

(4)示意图

三、线程管理————pthread

1、一套通用的多线程API,纯C语言,操作难度大,在iOS开发中基本不使用。

2、基本使用方式

#import <pthread.h>
    //线程编号的地址,本质是结构体类型
    pthread_t pthread;
    //方法的返回值:0 成功, 其它失败

     int result =  pthread_create(&pthread, NULL, demo, NULL);

    /*
    pthread_create函数的参数介绍    

    第一个参数:  线程编号的地址;
    第二个参数:  线程的属性;
    第三个参数: 线程要执行的方法,其中void *(*)(void *)具体代表含义:
        //函数的返回值类型: void *,类似于oc中的id;
        //函数的名称:函数指针;
        //函数的参数:void *;
        第四个参数:线程要执行的方法的参数。

    */

四、线程管理————NSThread

1、创建新线程的三种方式,例如:

//方式一:NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo:) object:nil];
[thread start];//方式二:
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:nil];
//方式三:准确的说此方法是NSObject的

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

2、NSThread在调试中的使用

  • 获得线程的属性:name,stackSize,threadPriority(默认0.5)
  • 管理线程的类方法:start、exit、sleep
  • 获得当前线程和主线程:   [NSThread currentThread]  、[NSThread mainThread];

五、线程管理————GCD

在之前文章中,已经针对GCD的基本使用做了详细介绍,不在这里复述了。可参阅:http://www.cnblogs.com/cleven/p/5249246.html

本文只对GCD的其他操作进行一些补充。

1、延迟操作

实例:

//延时操作
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  });
        /*
        dispatch_after的参数
    参数1  dispatch_time_t when
    多少秒之后执行
    参数2  dispatch_queue_t queue
    任务添加到那个队列
    参数3  dispatch_block_t block
    要执行的任务
    */

2、一次性执行

(1)定义:程序运行中只执行一次。一次性执行是线程安全的,可以使用一次性执行创建单例对象,效率比互斥锁高。

(2)实现:可以用来创建单例对象。

    //原理:当onceToken为0时执行方法,然后将全局变量oneceToken更改为-1,以后就无法再执行。
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    //要执行一次的代码;
    });

3、调度组

(1)定义:有时候需要在多个异步任务都执行完成之后继续做某些事情,比如下载歌曲,等所有的歌曲都下载完毕之后转到主线程提示用户,这样需要一个顺序的统一调度。

(2)实现:

//1 全局队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    //2 调度组
    dispatch_group_t group = dispatch_group_create();
    //3 添加任务
    //把任务添加到队列,等任务执行完成之后通知调度组,任务是异步执行
    dispatch_group_async(group, queue, ^{
        NSLog(@"歌曲1下载完毕  %@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"歌曲2下载完毕  %@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"歌曲3下载完毕  %@",[NSThread currentThread]);
    });
    //4 所有任务都执行完成后,获得通知 (异步执行)
    //等调度组中队列的任务完成后,把block添加到指定的队列
    dispatch_group_notify(group, queue, ^{
        NSLog(@"所有歌曲都已经下载完毕!   %@",[NSThread currentThread]);
    });
 
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        //在主线程,更新UI控件,提示用户
        NSLog(@"播放器更新完毕!  %@",[NSThread currentThread]);
    });
    NSLog(@"over");

(3)原理:

//1 全局队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
 
    //2 调度组
    dispatch_group_t group = dispatch_group_create();
 
    //ARC中不用写
//    dispatch_retain(group);
    //3 进入调度组,执行此函数后,再添加的异步执行的block都会被group监听
    dispatch_group_enter(group);
    
    //4 添加任务一
    dispatch_async(queue, ^{
        NSLog(@“下载第一首歌曲!”);
        dispatch_group_leave(group);
        //ARC中此行不用写,也不能写
//        dispatch_release(group);
    });
    //5 添加任务二
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@“下载第二首歌曲”);
        dispatch_group_leave(group);
        //ARC中此行不用写,也不能写
        //dispatch_release(group);
    });
    
    //6  获得调度组的通知
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@“歌曲都已经下载完毕! %@",[NSThread currentThread]);
    });
//7 等待调度组 监听的队列中的所有任务全部执行完毕,才会执行后续代码,会阻塞线程(很少使用)
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

六、线程管理————NSOperation

1、NSOperation的作用以及特点

(1)NSOperation是OC语言中基于GCD的面向对象的封装,NSOperation是iOS2.0推出的,iOS4之后(GCD出现)重写了NSOperation。

(2)使用起来比GCD更加简单(面向对象)。同时,苹果推荐使用,使用NSOperation不用关心线程以及线程的生命周期。

(3)提供了一些用GCD不好实现的功能,比如暂停,取消,最大并发数、依赖关系。当然GCD也有自己的特有,比如延迟、一次性执行、调度组。

(4)NSOperation是抽象类,约束子类都具有共同的属性和方法,不能直接使用,而是使用其子类。

(5)任务是并发执行的,除非遇到主队列(start方法除外)。

2、NSOperationQueue 队列

(1)两种队列

  • 并发队列:程序员自己创建
  • 主队列:系统创建

(2)NSOperationQueue的作用:

  • NSOperation可以调用start方法来执行任务,但默认是主线程执行的。如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作。

(3)无论是使用start还是加入队列的方式来执行操作,系统都会调用NSOperation中的main方法,所以如果自定义NSOperation,就要重写此方法。

(4)添加操作到队列(主队列也一样)

    - (void)addOperation:(NSOperation *)op;
    - (void)addOperationWithBlock:(void (^)(void))block;    

(5) 其他一些常用方法和属性

  • (BOOL)suspended                                        暂停
  • (NSUInteger)operationCount                         队列中的操作数
  • (NSUInteger)maxConcurrentOperationCount  最大并发数
  • +(NSOperation*)mainQueue                         获得主队列
  • +(NSOperation*)currentQueue                      获得当前队列
  • -(void)cancelAllOperations                             取消所有操作

3、NSOperation子类——NSInvocationOperation

(1)实例

//建NSInvocationOperation对象
    - (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
//调用start方法开始执行操作,一旦执行操作,就会调用target的sel方法
    - (void)start;

(2)注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作,只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作。

4、NSOperation子类——NSBlockOperation

(1)实例:

//创建NSBlockOperation对象
    + (id)blockOperationWithBlock:(void (^)(void))block;
//通过addExecutionBlock:方法添加更多的操作
    - (void)addExecutionBlock:(void (^)(void))block;

(2)注意:只要NSBlockOperation封装的操作数 > 1,就会异步执行操作。

    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@",[NSThread currentThread]);
    }];
    //操作添加额外的任务
    [op addExecutionBlock:^{
        NSLog(@"Execution %@",[NSThread currentThread]);
    }];
    [op start];

    //如果NSBlockOperation的操作数>1 开启新的线程
    //这时有两个任务并发执行,一个在主线程,一个在新开启的线程

5、并发数

(1)定义:同时执行的任务数,比如,同时执行3个任务放到3个线程,并发数就是3。

(2)最大并发数及相关方法:最大并发数是系统同一时间并发执行任务的最大数。系统可以开辟多个线程、队列可以拥有多个任务,但是同时执行的任务数只能是设定好的最大并发数,直到队列中任务执行完毕。

  • - (NSInteger)maxConcurrentOperationCount;
  • - (void)setMaxConcurrentOperationCount:(NSInteger)cnt

(3)执行的过程

  a、把操作添加到队列

  b、去线程池去取空闲的线程,如果没有就创建线程

  c、把操作交给从线程池中取出的线程执行

  d、执行完成后,把线程再放回线程池中

  e、重复b,c,d直到所有的操作都执行完

6、优先级

(1)方法一设置NSOperation在queue中的优先级,可以改变操作的执行优先级,注意这是NSOperation中的属性,已经不推荐使用了。

  • - (NSOperationQueuePriority)queuePriority;
  • - (void)setQueuePriority:(NSOperationQueuePriority)p;

(2)方法二:iOS8以后推荐使用服务质量 qualityOfService属性,这是个枚举值。

(3)注意:优先级只是告诉系统:在CUP随机调度的情况下,请尽量优先调用优先级高的任务去执行,并不能绝对保证CPU全部执行优先级高的任务。

7、依赖关系

(1)定义:类似于GCD的串行队列,NSOperation之间可以设置依赖来保证执行顺序。

(2)实例

 NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op1 验证账号");
    }];

    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op2 扣费");
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op3 下载应用");
    }];
    //操作依赖 不能设置相互依赖
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    //把操作添加到队列中 waitUntilFinished是否等待这句代码执行完毕再来执行下面的代码
    [self.queue addOperations:@[op2,op3] waitUntilFinished:NO];

    //不同的队列之间也可以设置依赖关系
    [[NSOperationQueue mainQueue]addOperation:op1];

8、监听操作的完成

(1)类似于GCD的操作组,NSOperation也可以监听操作的完成,这是NSOperation中的方法:

  • - (void (^)(void))completionBlock;
  • - (void)setCompletionBlock:(void (^)(void))block;
   //创建操作op,任务就是循环打印输出
        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
            for (int i = 0; i < 20; i++) {
                 NSLog(@"我是op===》 %d",i);
             }
        }];
    //设置操作优先级 最高的服务质量
    op.qualityOfService = NSQualityOfServiceUserInteractive;
    //把操作添加到队列中
        [self.queue addOperation:op];
    //监听op的完成
    [op setCompletionBlock:^{
        NSLog(@"op 执行完毕了! %@",[NSThread currentThread]);
    }];

    //创建操作op2
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i <20; i++) {
            NSLog(@"我是op2+++》 %d",i);
        }
    }];
    //设置操作优先级 最低的服务质量
    op2.qualityOfService = NSQualityOfServiceBackground;
    //把操作添加到队列中
    [self.queue addOperation:op2];

    //本例中加入了优先级的使用:op和op2两个任务,op要优先于op2被CPU调度,理论上也是会优先于op2执行完毕,当op执行完毕时,op任务的结束被监听到,输出“执行完毕”,此时op2还在执行中。
    

七、线程间通信的几种方式

线程间的通讯,关键在于获得不同的线程或队列,然后在不同线程中执行任务,比如从子线程到主线程,再从主线程到子线程。

1、获得当前线程(队列)的方式

(1) NSThread管理线程:           [NSThread currentThread];

(2) NSOperation管理线程:       [NSOperationQueue currentQueue];

 2、获得主线程(主队列)的方式

(1) NSThread管理线程:           [NSThread mainThread];  主线程

(2) NSOperation管理线程:       [NSOperationQueue mainQueue]; 主队列

(3)GCD管理线程:                  dispatch_get_main_queue(); 主队列

3、在某线程中执行

(1)此方法是NSObject的扩展(NSThread.h中):

  • - (void)performSelectorOnMainThread

(2)开启新线程执行:

  • - (void)performSelectorInBackground

(3)在某个线程中执行:

  • -(void)performSelector:onThread:

到此处,本文只是简单的将iOS中多线程的基本概念和使用做了简单介绍和整理,如有问题,还望多包含并指教,随后将更多讨论些在实际开发中的应用。

时间: 2024-10-05 19:14:37

iOS开发——多线程的相关文章

iOS开发多线程篇—线程的状态

iOS开发多线程篇—线程的状态 一.简单介绍 线程的创建: self.thread=[[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil]; 说明:创建线程有多种方式,这里不做过多的介绍. 线程的开启: [self.thread start]; 线程的运行和阻塞: (1)设置线程阻塞1,阻塞2秒 [NSThread sleepForTimeInterval:2.0]; (2)第二种设置线程阻塞2,以当前时

iOS开发多线程之自定义NSOperation

iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UITableViewController. 1 // 2 // YYViewController.h 3 // 01-自定义Operation 4 // 5 // Created by apple on 14-6-26. 6 // Copyright (c) 2014年 itcase. All rig

iOS开发多线程篇—自定义NSOperation

iOS开发多线程篇—自定义NSOperation 一.实现一个简单的tableView显示效果 实现效果展示: 代码示例(使用以前在主控制器中进行业务处理的方式) 1.新建一个项目,让控制器继承自UITableViewController. 1 // 2 // YYViewController.h 3 // 01-自定义Operation 4 // 5 // Created by apple on 14-6-26. 6 // Copyright (c) 2014年 itcase. All rig

iOS开发多线程篇 09 —NSOperation简单介绍

iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作?:配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperationQueue实现多线程的具体步骤: (1)先将需要执行的操作封装到一个NSOperation对象中 (2)然后将NSOperation对象添加到NSOperationQueue中 (3)系统会?动将NSOperationQueue中的NSOpe

iOS开发多线程篇 05 —GCD介绍

iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核.四核) GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码 3.提示 (1)GCD存在于libdispatch.dylib这个库中

iOS开发多线程篇—多线程简单介绍

iOS开发多线程篇—多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过“活动监视器”可以查看Mac系统中所开启的进程 2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行 3.线程

iOS开发多线程篇—多线程的的相关概念(1)

iOS开发多线程篇-多线程简单介绍 一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开QQ.Xcode,系统就会分别启动2个进程 通过"活动监视器"可以查看Mac系统中所开启的进程 2.什么是线程 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行

IOS开发——多线程编程

1."省电,流畅,优质应用,响应速度快,用户体验好--"也许是众多用户眼中的苹果系统. 2.在众手机商拼CPU主频,拼4核,8核的年代,苹果依然坚持双核,iphone用户体验仍然坚挺. 以上两点IOS是如何优化,在续航,流畅度和响应速度上完胜安卓,答案就是多线程&RunLoop... RunLoop是IOS事件响应与任务处理最核心机制,它贯穿IOS整个系统运作. RunLoop不像一般的线程循环等待任务,传统的线程循环等待任务会导致CPU时间被占用,虽然你设置了睡眠时间,但很多

iOS开发多线程篇—GCD的基本使用

iOS开发多线程篇—GCD的基本使用 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程. 获取主队列的方式: dispatch_queue_t queue=dispatch_get_main_queue(); (1)使用异步函数执行主队列中得任务,代码示例: 1 // 2 // YYViewController.m 3 //

iOS开发多线程篇 10 —NSOperation基本操作

iOS开发多线程篇—NSOperation基本操作 一.并发数 (1)并发数:同时执?行的任务数.比如,同时开3个线程执行3个任务,并发数就是3 (2)最大并发数:同一时间最多只能执行的任务的个数. (3)最?大并发数的相关?方法 - (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger)cnt; 说明:如果没有设置最大并发数,那么并发的个数是由系统内存和CPU决定的,可能