热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS多线程编程

iOS多线程编程1.进程,线程,任务进程:一个程序在运行时,系统会为其分配一个进程,用以管理他的一些资源。线程:进程内所包含的一个或多个执行单元称为线程,线程一般情况下不持有资源,

iOS多线程编程

1. 进程,线程, 任务

   进程:一个程序在运行时,系统会为其分配一个进程,用以管理他的一些资源。

   线程:进程内所包含的一个或多个执行单元称为线程,线程一般情况下不持有资源,但可以使用其所在进程的资源。

   任务:进程或线程中要做的事情。

   在引入线程的操作系统中,通常把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。

    线程比进程更小,对其调度的开销小,能够提高系统内多个任务的并发执行程度。

    一个程序至少有一个进程,一个进程至少有一个线程.一个程序就是一个进程,而一个程序中的多个任务则被称为线程。

    线程只能归属于一个进程并且它只能访问该进程所拥有的资源。当操作系统创建一个进程后,该进程会自动申请一个名为主线程或首要线程的线程。应用程序(application)是由一个或多个相互协作的进程组成的。

    多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。

2. iOS多线程编程技术

    共有三种(实际上是四种,还有Pthreads,C语言框架)

    > NSThread

    > NSOperation

    > GCD (Grand Central Dispatch)

    从上到下,封装度从低到高,封装度越高使用越简单,也是官方推荐使用。

    三种方式的比较:

    NSThread:  相对于另外两种是比较轻量级的。此种方式是经官方封装后的,是完全面向对象的,所以可以直接操控线程对象,非常直观方便。但是需要自己管理线程的生命周期,线程同步,而且线程同步对数据的加锁会有一定的系统开销。使用比较简单,但不够智能,在一些简单的场景才使用。

    NSOperation: 完全面向对象的。相关的主要类有 NSOperation(任务) 和 NSOperationQueue(任务队列),其中NSOperationQueue 在iOS4引入GCD后,其内部用GCD实现的。此种方式下不需要关心线程管理,数据同步的操作。隐藏了许多复杂的代码,提供了简单的API。

    GCD : 是苹果为多核并行运算提出的解决方案,会自动合理的利用更多的CPU内核(如双核,四核)。此种方式也能自动管理线程的生命周期(创建线程,调度任务,销毁线程),不需要自己管理,只需要告诉其要做的操作是什么就可以。虽然也使用c语言,但因为使用了block, 使用也很方便,灵活。在GCD中也有“任务”,“队列”的概念。

一、NSThread  ===========================================

1. 使用NSThread创建并管理线程

   > 创建线程

      方式一:实例方法

      [NSThread alloc] initWithTarget: selector : object:]

      参数一:线程操作消息的接收者 self

      参数二:选择器方法,线程操作的方法,此方法只能带一个参数,而且不能有返回值

      参数三:线程操作方法所带的参数

      使用该方式创建的线程不会自动启动,需调用线程方法:

      [thread start]  // 开始启动并执行线程

      方式二:类方法

      [NSThread detachNewThreadSelector: toTarget: withObject: ]

      参数同上同名参数;

      此方法创建的线程会自动启动执行,无需手动开启。

    > 线程方法

       //取消线程

       - (void)cancel;

       //启动线程

       - (void)start;

       //设置/获取某个线程的状态

       @property (readonly, getter=isExecuting) BOOL executing;

       @property (readonly, getter=isFinished) BOOL finished;

       @property (readonly, getter=isCancelled) BOOL cancelled;

       //设置和获取线程名字

       -(void)setName:(NSString *)n;

       -(NSString *)name;

       //获取当前线程

       + (NSThread *)currentThread;

       //获取主线程

       + (NSThread *)mainThread;

       //使当前线程暂停一段时间,或者暂停到某个时刻

       + (void)sleepForTimeInterval:(NSTimeInterval)time;

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

       // 设置线程优先级

       + (BOOL)setThreadPriority:(double)p;

      > 线程间的通信

       在非主线程上绝对不能去访问UI, 必须在主线程上更新

       [self performSelectorOnMainThread:@selector(updateUI:) withObject:data waitUntilDone:YES];

       线程与线程间可进行数据通讯

       [self performSelector:@selector(senddata:) onThread:thread2 withObject:obj waitUntilDone:YES]

      > 线程同步

        多个线程访问同一共享资源时,为保证数据资源的准确性,需对资源进行加锁,是在一个时刻上只有一个线程访问共享资源,其他线程则排队等待。

         NSLock 锁

         [[NSLock alloc] init]

         [theLock lock];

         …..要访问的共享资源

         [theLock unlock];

二、NSOperation========================================================

1. NSOperation

   此类是抽象类不能直接使用。

   只能使用系统定义好的子类或者自定义继承NSOperation。

   定义好的子类:NSInvocationOperation 和 NSBlockOperation

   一个 NSOperation对象 对应一个任务/线程,需要将其放入 NSOperationQueue 任务队列/线程池,才会启动并执行任务/线程。 

 2. NSInvocationOperation

   任务的操作执行在方法中进行

   > [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(..) object:nil]   

3. NSBlockOperation

   任务的操作执行在block中进行

   > [NSBlockOperation blockOperationWithBlock:^{

        …

    }]

4. NSOperationQueue 将任务添加到任务队列中使其启动执行

   > NSOperationQueue *que = [[NSOperationQueue alloc] init]  // 自定义队列

   > que.name // 队列名称

   > que.maxConcurrentOperationCount  // 最大任务并发数,设置为1时为串行执行任务。默认是-1,表示没有限制,会同时执行队列中的任务。

   > [que addOperation:oper1]  // 将任务添加到队列中以启动执行

   除自定义队列外:

   主队列(该队列中的任务在主线程执行):[NSOperationQueue mainQueue]

   当前队列:[NSOperationQueue currentQueue]   

5. 任务间的依赖

   [oper1 addDependency:oper2] // 任务1依赖于任务2,任务1的执行必须等任务2执行完毕后才能开始

   注意此操作必须是在将任务添加到队列前执行!!!

6. SDWebImage 图片下载原理运用了NSOperation,NSOperationQueue

三、GCD============================================================

1. GCD:任务,队列

   队列分串行,并行队列。

   串行队列中的任务执行:GCD会FIFO(先进先出)的取出一个任务,执行一个后,再获取下一个,依次类推。

   并行队列中的任务执行:GCD也是按FIFO的方式取出任务,与串行的不同是:取出任务后会放倒别的线程上,然后再取出一个放到另外的线程....。 因为取任务的过程很快,看起来所有任务都是一起执行的。注意:GCD会根据系统资源控制并行的任务数量,任务太多时,不会让所有任务同时执行。

2. 从程序上队列分类:

   主队列:(串行队列)dispatch_queue_t qm = dispatch_get_main_queue();

   自定义队列:(可串行,并行)dispatch_queue_t qself = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT); // 通过第二个参数指定队列是串行DISPATCH_QUEUE_SERIAL还是并行DISPATCH_QUEUE_CONCURRENT

   全局并行队列:dispatch_queue_t qg = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

3. 队列中添加要执行的任务(同步[阻塞当前线程],异步任务[不阻塞当前线程])

    dispatch_async(qm, ^{

        // 在指定的队列中要执行的任务...

    });

4. 队列组

    多个队列可以放到一个组中。

   // 创建队列组 

   dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group, queue, ^{

        // 在指定的队列组中,添加队列queue, 并在queue中添加任务...

    });

    dispatch_group_notify(group, queue, ^{

        // 指定的组里的所有任务完成后,发送通知给指定的队列,并执行一个任务…,通常用于在主队列中更新ui

    });

iOS多线程编程


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
author-avatar
马丁乐_449
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有