1.NSThread

2.NSOperationQueue

3.GCD

NSThread:

创建方式主要有两种:

[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];

NSThread* myThread = [[NSThread alloc] initWithTarget:self
selector:@selector(myThreadMainMethod:)
object:nil];
[myThread start]; //启动线程

这两种方式的区别是:前一种一调用就会立即创建一个线程来做事情;而后一种虽然你 alloc 了也 init了,但是要直到我们手动调用 start 启动线程时才会真正去创建线程。这种延迟实现思想在很多跟资源相关的地方都有用到。后一种方式我们还可以在启动线程之前,对线程进行配置,比如设置 stack 大小,线程优先级。
此外还有一种间接的方式:利用NSObject的方法
performSelectorInBackground:withObject: 来创建一个线程:
[myObj performSelectorInBackground:@selector(myThreadMainMethod) withObject:nil]; //在后台运行某一个方法
其效果与 NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一样的。

NSOperationQueue

The NSOperation class is an abstract class you use to encapsulate the code and data associated with a single task. Because it is abstract, you do not use this class directly but instead subclass or use one of the system-defined subclasses (NSInvocationOperation or NSBlockOperation) to perform the actual task.
并发执行你需要重载如下4个方法
//执行任务主函数,线程运行的入口函数
-(void)start
//是否允许并发,返回YES,允许并发,返回NO不允许。默认返回NO
-(BOOL)isConcurrent
- (BOOL)isExecuting
//是否已经完成,这个必须要重载,不然放在放在NSOperationQueue里的NSOpertaion不能正常释放。
- (BOOL)isFinished

比如TestNSOperation:NSOperaion 重载上述的4个方法,
声明一个NSOperationQueue,NSOperationQueue *queue = [[[NSOperationQueue alloc ] init]autorelease];
[queue addOperation:testNSoperation];
它会自动调用TestNSOperation里的start函数,如果需要多个NSOperation,你需要设置queue的一些属性,如果多个NSOperation之间有依赖关系,也可以设置,具体可以参考API文档。

(2)非并发执行
-(void)main
只需要重载这个main方法就可以了。

dispatch_async(dispatch_queue_t queue,dispatch_block_t block);
async表明异步运行,block代表的是你要做的事情,queue则是你把任务交给谁来处理了.

之所以程序中会用到多线程是因为程序往往会需要读取数据,然后更新UI.为了良好的用户体验,读取数据的操作会倾向于在后台运行,这样以避免阻塞主线程.GCD里就有三种queue来处理。

GCD
1. Main queue:
  顾名思义,运行在主线程,由dispatch_get_main_queue获得.和ui相关的就要使用MainQueue.
2.Serial quque(private dispatch queue)
  每次运行一个任务,可以添加多个,执行次序FIFO. 通常是指程序员生成的.
3. Concurrent queue(globaldispatch queue):
可以同时运行多个任务,每个任务的启动时间是按照加入queue的顺序,结束的顺序依赖各自的任务.使用dispatch_get_global_queue获得.
所以我们可以大致了解使用GCD的框架:
1
2
3
4
5
6
7
dispatch_async(getDataQueue,^{
//获取数据,获得一组后,刷新UI.
dispatch_aysnc(mainQueue, ^{
//UI的更新需在主线程中进行
};
}
)
下面 就来总结一下这三种多线程方式的区别吧:
Thread 是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部分内存空间, 它们拥有对数据相同的访问权限。你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread:
Cocoa threads: 使用NSThread 或直接从 NSObject 的类方法 performSelectorInBackground:withObject: 来创建一个线程。如果你选择thread来实现多线程,那么 NSThread 就是官方推荐优先选用的方式。

Cocoa operations是基于 Obective-C实现的,类 NSOperation 以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心线程的管理,同步等事情,因为NSOperation已经为我 们封装了这些事情。 NSOperation 是一个抽象基类,我们必须使用它的子类。iOS 提供了两种默认实现:NSInvocationOperation 和 NSBlockOperation。

Grand Central Dispatch (GCD): iOS4 才开始支持,它提供了一些新的特性,以及运行库来支持多核并行编程,它的关注点更高:如何在多个 cpu 上提升效率。

最后,既然说道多线程的开发,难免会在多线程之间进行通讯;
利用NSObject的一些类方法,可以轻松搞定。

在应用程序主线程中做事情:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array

在指定线程中做事情:
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array
在当前线程中做事情:
//Invokes a method of the receiver on the current thread using the default mode after a delay.
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

performSelector:withObject:afterDelay:inModes:

取消发送给当前线程的某个消息
cancelPreviousPerformRequestsWithTarget:

cancelPreviousPerformRequestsWithTarget:selector:object:

如在我们在某个线程中下载数据,下载完成之后要通知主线程中更新界面等等,可以使用如下接口:- (void)myThreadMainMethod
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// to do something in your thread job
...
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
[pool release];

ios多线程开发的常用三种方式的更多相关文章

  1. Android 音视频开发(一) : 通过三种方式绘制图片

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7456956.html 在 Android 音视频开发学习思路 里面,我们写到了,想要逐步入门音视频开发,就 ...

  2. php集成开发环境搭建三种方式

    三种方式都是一键搭建php开发环境 三种方式前提都是在linux下 wamp和phpstudy就不再用了 首先打造linux开发环境,通过vagrant+vbox实现本地文件同步到虚拟机上进行同步开发 ...

  3. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  4. Spring:Spring-IOC实例化bean的常用三种方式

    Spring容器提供了三种对bean的实例化方式: 1)构造器实例化 public class Demo { private String name; //getter和setter方法略 } < ...

  5. iOS中枚举定义的三种方式

    最简单的方式 typedef enum{ num1 = 0, num2 = 1, num3 = 2 }num; 同时我们还可以使用NS_ENUM的方式定义枚举 typedef NS_ENUM (NSI ...

  6. iOS 滑动隐藏导航栏-三种方式

    /** 1隐藏导航栏-简单- */    self.navigationController.hidesBarsOnSwipe = YES; /** 2隐藏导航栏-不随tableView滑动消失效果 ...

  7. 详细理解servlet实现的三种方式和生命周期

    阅读目录 开发servlet的三种方式 理解实现servlet接口的方式,理解servlet生命周期 Servlet接口有五个方法 继承GenericServlet 继承HttpServlet 现在很 ...

  8. IOS 多线程,线程同步的三种方式

    本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...

  9. iOS开发 跳转场景的三种方式

    iOS开发 跳转场景的三种方式 2012年10月17日, 15:32 假设A跳转到B,三种方法:1.按住ctrl键,拖动A上的控件(比如说UIButton)到B上,弹出菜单,选择Modal.不需要写任 ...

随机推荐

  1. build.xml详解

    build.xml详解1.<project>标签每个构建文件对应一个项目.<project>标签时构建文件的根标签.它可以有多个内在属性,就如代码中所示,其各个属性的含义分别如 ...

  2. Rhel6-pacemaker+drbd配置文档

    系统环境: rhel6 x86_64 iptables and selinux disabled 主机: 192.168.122.119 server19.example.com 192.168.12 ...

  3. enmo_day_01

    OCP : 三门,sql, 管理一,管理二 VUE 考试中心 OCM : 2天,5年经验 11g grid 12c cloud 个人技术博客 itpub, csdn, 51blog 自己买主机,域名, ...

  4. 一个null引发的错误

    写程序时,发生一个unrecognized selector的错误,很显然,这是一个经典错误,运行时找不到可调用的方法. 系统提示的reason是 -[NSNull length] 错误 经过查找,原 ...

  5. 字符串中带有emoji表情处理

    1:先删除字符然后解析当前字符再显示 edit.addTextChangedListener(new TextWatcher() { @Override public void beforeTextC ...

  6. 利用反射将Datatable、SqlDataReader转换成List模型

    1. DataTable转IList public class DataTableToList<T>whereT :new() { ///<summary> ///利用反射将D ...

  7. windows在当前位置打开终端

    1) 在此文件夹窗口内空白区域右键单击(需要同时按住Shift),从菜单中选择"在此处打开命令行窗口"的项:2) 在此窗口地址栏里直接输入cmd,回车即可.

  8. Python OpenCV —— bitwise

    关于图像的位操作,目的是为了将一个logo覆盖到另一个图片上. # -*- coding: utf-8 -*- """ Created on Wed Sep 28 20: ...

  9. 从零开始学习Node.js例子四 多页面实现数学运算

    app-node.js ; var http = require('http'); var htutil = require('./htutil'); var server = http.create ...

  10. url中的百分号转译

    有一次发现自己输入的url中含有中文的时候,他会转化为%XXXX的格式. 于是想怎么把他给转换回去,于是使用了urllib库 #-*-coding:utf8 -*- import urllib url ...