ios学习--多线程技术

进程与线程概念

--一个运行的程序就是一个进程或者叫做一个任务
--一个进程至少包含一个线程,线程是程序的执行流
--iOS程序启动时,在创建一个进程的同时, 会开始运行一个线程,该线程被称为主线程
--主线程是其他线程最终的父线程,所有界面的显示操作必须在主线程进行!!!
--系统中的每一个进程都有自己独立的虚拟内存空间,而同一个进程中的多个线程则共用进程的内存空间
--每创建一个新的线程,都会消耗一定内存和CPU时间
--当多个线程对同一个资源出现争夺的时候需要注意线程安全问题

多线程的优势与难点

--优势
*充分发挥多核处理器优势,将不同线程任务分配给不同的处理器,真正进入“并行运算”状态
*将耗时、轮询或者并发需求高等任务分配到其他线程执行,并由主线程负责统一更新界面会使得应用程序更加流畅,用户体验更好
*当硬件处理器的数量增加,程序会运行更快,而无需做任何调整
--难点
*共享资源的“争夺”
*多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了通过提高资源使用效率来提高系统的整体性能

多线程使用注意事项

--线程使用不是无节制的
*iOS中的主线程的堆栈大小是1M
*从第二个线程开始都是512KB
*这些数值不能通过编译器开关或线程API函数更改
--只有主线程有直接修改UI的能力

iOS的三种多线程技术

1.NSThread
2.NSOperation
3.GCD —— Grand Central Dispatch,是基于C语言的框架
以上这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。但是就目前而言,iOS的开发者,需要了解三种多线程技术的基本使用过程。因为很多框架技术分别使用了不同多线程技术。例如NSURLConnection的异步静态方法:
sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)

三种多线程技术的对比

NSThread:
优点:NSThread 比其他两个轻量级,使用简单
缺点:需要自己管理线程的生命周期、线程同步。线程同步对数据的加锁会有一定的系统开销
NSOperation:
不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
GCD:
Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术

NSThread

创建线程方法:
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
参数说明:
--selector:线程执行的方法,只能有一个参数,不能有返回值
--target:selector消息发送的对象
--argument:传输给target的唯一参数,也可以是nil
NSObject直接加入了多线程的支持,允许对象的某个方法在后台运行(本方法普遍应用在游戏中,利用多线程播放声音)
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;

代码演练

// 创建线程1
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil];
// 设置线程名称,因为需要通过线程名称跟踪线程执行情况,因此此处不使用线程静态方法
[thread1 setName:@"售票线程-1"];
// 启动线程1
[thread1 start];

// 创建线程2,步骤同上
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil];
[thread2 setName:@"售票线程-2"];
[thread2 start];

NSThread使用注意

*当涉及到共享资源争夺时,共享资源的数据加锁是一个难点,既要保证数据安全,又要保证线程执行效率
--使用前加锁
--尽快使用
--使用完解锁
--再去做其他的事情
*多线程编写顺序
1.单个方法调试OK
2.单个线程调试OK
3.增加线程,并考虑线程加锁、解锁的准确位置。
注意:
--只有主线程能够修改UI
--如果不涉及到内存争抢,NSThread写多线程是最简单的
*当不涉及共享资源争夺时,使用NSObject的performSelectorInBackground方法可以非常的方便地实现多线程

NSOperation & NSOperationQueue

*NSOperation的两个子类

1.NSInvocationOperation

2.NSBlockOperation
*工作原理:
--用NSOperation封装要执行的操作
--将创建好的NSOperation对象放NSOperationQueue中
--启动OperationQueue开始新的线程执行队列中的操作
*注意事项:
--使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢
--使用以下方法可以控制并发的线程数量:
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

NSOperation操作流程

1.定义操作

2.定义队列

3.将操作添加至队列,队列是自动启动的

代码演练

while (YES) {
    if (_tickets > 0) {
        // 在主线程操作队列更新界面
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            NSString *str = [NSString stringWithFormat:@"当前票数:%d,售票线程:%@", _tickets, operationName];
            [self appendTextView:str];
            _tickets--;
        }];
        // 模拟休息
        // ……
    } else {
        // 在主线程操作队列更新界面
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            NSString *str = [NSString stringWithFormat:@"票已售完,售票线程:%@", operationName];
            [self appendTextView:str];
        }];
        break;
    }
}

******NSInvocationOperation代码*********

// 设置预售票数,共享资源!
_tickets = 20;

// 定义操作1
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSaleMethod:) object:@"售票操作-1"];
// 定义操作2
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSaleMethod:) object:@"售票操作-2"];

// 定义操作队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation1];
[queue addOperation:operation2];

******NSBlockOperation代码*********

// 设置预售票数,共享资源!
_tickets = 20;

// 定义操作队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
    [self operationSaleMethod:@"售票操作-1"];
}];
[queue addOperationWithBlock:^{
    [self operationSaleMethod:@"售票操作-2"];
}];

NSOperation使用注意

--NSOperation中无需使用线程锁
--除更新UI之外,对共享资源的争夺也需放在主线程队列之中
--将定义的操作添加至队列之后,多线程便开始启动
--NSBlockOperation的使用相比NSInvocationOperation更加灵活、方便
--通过setMaxConcurrentOperationCount方法可以控制并发的最大线程数量

GCD

*GCD是基于C语言的框架
*工作原理:
--让程序平行排队的特定任务,根据可用的处理资源,安排它们在任何可用的处理器上执行任务
--要执行的任务可以是一个函数或者一个block
--底层是通过线程实现的,不过程序员可以不必关注实现的细节
--GCD中的FIFO队列称为dispatch queue,可以保证先进来的任务先得到执行
dispatch_notify可以实现监听一组任务是否完成,完成后得到通知
*dispatch queue:
--Main dispatch queue:是全局可用的队列,用于在主线程上执行任务
--Serial:同时只执行一个任务
--Concurrent:可以并发地执行多个任务,但是执行完成的顺序是随机的

GCD使用流程

1. 获取全局调度队列

2. 创建调度群组

3. 向调度群组添加异步任务,并指定执行队列

4. 接收群组调度完成通知,群组中所有任务完成后获得通知

代码演练

while (YES) {
    if (_tickets > 0) {
        // 在主调度队列更新界面
            dispatch_async(dispatch_get_main_queue(), ^{
            NSString *str = [NSString stringWithFormat:@"当前票数:%d,售票线程:%@", _tickets, gcdName];
            [self appendTextView:str];
            _tickets--;
        });
        // 模拟休息
            if ([gcdName isEqualToString:@"售票GCD-1"]) {
            [NSThread sleepForTimeInterval:0.1f];
        } else {
            [NSThread sleepForTimeInterval:0.2f];
        }
    } else {
        break;
    }
}

// 设置预售票数,共享资源!
_tickets = 20;

// 1. 获取默认调度优先级的全局调度队列,第二个参数为今后拓展使用,目前始终传入0
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

// 2. 创建任务调度组
dispatch_group_t group = dispatch_group_create();

// 3. 调度群组异步任务
dispatch_group_async(group, queue, ^{
    [self gcdSaleMethod:@"售票GCD-1"];
});
dispatch_group_async(group, queue, ^{
    [self gcdSaleMethod:@"售票GCD-2"];
});
// 4. 接收群组调度通知
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    [self appendTextView:@"票已售完"];
});

GCD使用注意

--GCD的原理和Operation非常相像,只是它是C语言架构的。
--GCD中无需使用线程锁
--除更新UI之外,对共享资源的争夺也需放在主调度队列之中
--将任务添加至群组,并指定全局操作队列,使得GCD的多线程更加灵活、方便
--dispatch_group_notify可以监听一组任务是否完成。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后,才通知界面说已经完成
--如果不需要监听一组任务,可以直接使用dispatch_async方法


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS开发指南第五版》是一本关于iOS应用开发的指南书籍。该书作者详细介绍了使用Objective-C语言和iOS SDK进行开发的基本知识和技术。 书中首先介绍了iOS开发的基本概念和框架,包括应用生命周期、视图控制器、界面布局、响应事件等。作者通过详细的示例代码和说明,帮助读者理解和掌握各种构建iOS应用的常用技术。 书中还介绍了iOS应用的数据存储和网络通信技术。作者详细讲解了使用Core Data框架进行数据存储的方法,以及使用网络通信框架进行数据传输的技巧。读者可以根据书中的示例代码和说明,在开发应用时轻松处理数据和网络通信的需求。 此外,书中还涵盖了iOS应用的用户界面设计和动画效果实现。作者介绍了常用的界面元素、布局方式和自定义控件的开发方法,并详细演示了如何实现各种动画效果,使应用更加生动和用户友好。 在最后几章中,作者还介绍了iOS应用的高级开发技术,包括多线程编程、性能优化和测试等。通过学习这些内容,读者可以提高应用的性能和稳定性,为用户提供更好的使用体验。 总之,《iOS开发指南第五版》是一本对于想学习iOS开发的读者来说十分实用的书籍。作者通过清晰的结构和丰富的示例代码,将复杂的开发技术变得易于理解和掌握。无论是初学者还是有一定经验的开发者,都可以从中获得很多实用的知识和技巧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值