iOS多线程的几种创建方式

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的框架:

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:

示例:

 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 2 {
 3     self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
 4
 5     //创建线程的第一种方式
 6     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"universe"];
 7     [thread start];
 8     [thread release];
 9
10
11     //创建线程的第二种方式,NSThread类方法
12     [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"yuzhou"];
13
14
15     //创建线程的第三种方法  NSObject方法
16     [self performSelectorInBackground:@selector(run:) withObject:@"nsobject thread"];
17
18     //创建线程的第四种方式
19     NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init];
20     [oprationQueue addOperationWithBlock:^{
21         //这个block语句块在子线程中执行
22         NSLog(@"oprationQueue");
23     }];
24     [oprationQueue release];
25
26     //第五种创建线程的方式
27     NSOperationQueue *oprationQueue1 = [[NSOperationQueue alloc] init];
28     oprationQueue1.maxConcurrentOperationCount = 1;//指定池子的并发数
29
30     //NSOperation 相当于java中的runnable接口,继承自它的就相当一个任务
31     NSInvocationOperation *invation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"invation"];
32     [oprationQueue1 addOperation:invation];//将任务添加到池子里面,可以给池子添加多个任务,并且指定它的并发数
33     [invation release];
34
35     //第二个任务
36     NSInvocationOperation *invation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2:) object:@"invocation2"];
37     invation2.queuePriority = NSOperationQueuePriorityHigh;//设置线程优先级
38     [oprationQueue1 addOperation:invation2];
39     [invation2 release];
40
41     [oprationQueue1 release];
42
43     //调用主线程,用来子线程和主线程交互,最后面的那个boolean参数,如果为yes就是等这个方法执行完了在执行后面的代码;如果为no的话,就是不管这个方法执行完了没有,接着往下走
44     [self performSelectorOnMainThread:@selector(onMain) withObject:self waitUntilDone:YES];
45
46     //---------------------GCD----------------------支持多核,高效率的多线程技术
47     //创建多线程第六种方式
48     dispatch_queue_t queue = dispatch_queue_create("name", NULL);
49     //创建一个子线程
50     dispatch_async(queue, ^{
51         // 子线程code... ..
52         NSLog(@"GCD多线程");
53
54         //回到主线程
55         dispatch_sync(dispatch_get_main_queue(), ^{//其实这个也是在子线程中执行的,只是把它放到了主线程的队列中
56             Boolean isMain = [NSThread isMainThread];
57             if (isMain) {
58                 NSLog(@"GCD主线程");
59             }
60         });
61     });
62
63
64     self.window.backgroundColor = [UIColor whiteColor];
65     [self.window makeKeyAndVisible];
66     return YES;
67 }
68
69 - (void)onMain
70 {
71     Boolean b = [NSThread isMainThread];
72     if (b) {
73         NSLog(@"onMain;;%d",b);
74     }
75 }
76
77
78 - (void) run:(NSString*)str
79 {
80     NSLog(@"多线程运行:::%@",str);
81 }
82 - (void) run2:(NSString*)str
83 {
84     NSLog(@"多线程运行:::%@",str);
85 }
时间: 2024-08-26 12:21:18

iOS多线程的几种创建方式的相关文章

java中多线程的两种创建方式

一丶继承Thread类实现多线程 第一步:继承Thread类第二步:重写run()方法第三步:创建继承了Thread类的对象 , 调用start()方法启动. //线程创建方式一 : /* 第一步:继承Thread类 第二步:重写run()方法 第三步:创建继承了Thread类的对象 , 调用start()方法启动. */ public class TestThread extends Thread{ @Override public void run() { for (int i = 0; i

多线程的四种创建方式--前两种不常用

- (void)viewDidLoad { [super viewDidLoad]; //1.Datach 方式,隐式创建 //    [NSThread detachNewThreadSelector:@selector(detachMethod) toTarget:self withObject:nil]; //2.NSObject的perform方法,隐式创建 //    [self performSelectorInBackground:@selector(detachMethod) w

关于多线程的两种创建方式的用法和选择

本文分别说明的继承Thread类和Runnable接口的两种方式.仅为个人见解,如有不妥还清指出. 先说一下并发和并行, 并行:多个任务可以同时做,常用与任务之间比较独立,互不影响.相当于很多人做很多件事(例学校篮球场,很多学生在不同的场地打球) 并发:相当于很多人在一个篮球场打球,只能轮着上因为只有一片场地. 首先第一种是继承Thread类的方法 直接上代码,实现的是火车票卖票的问题 class Windows extends Thread{ private static int ticket

Java---11---多线程的两种创建方式

多线程的两种创建方式: 下面这些东西是API文档中的: public class Thread extends Object implements Runnable 线程 是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程.每个线程都可以或不可以标记为一个守护程序.当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

iOS 页面间几种传值方式(属性,代理,block,单例,通知) 姜糖水 2015-05-03 52 阅读 iOS 移动开发 第二个视图控制器如何获取第一个视图控制器的部分信息 例如 :第二个界面中的lable显示第一个界面textField中的文本 这就需要用到属性传值.block传值 那么第一个视图控制器如何获的第二个视图控制器的部分信息 例如:第一个界面中的lable显示第二个界面textField中的文本 这就需要使用代理传值 页面间传值有八大传值方式,下面我们就简单介绍下页面间常用的五

单例模式的7种创建方式

1.饿汉式 public final class SingletonObject1 { private static final SingletonObject1 instance = new SingletonObject1(); private SingletonObject1() { } public static SingletonObject1 getInstance() { return instance; } } 饿汉式的创建方法关键在于 instance作为类变量直接得到了初始化

JavaLearning:多线程的两种实现方式

第一种 继承Thread类 package org.fan.threaddemo; public class MyThread extends Thread{ private String name; public MyThread(String name){ this.name=name; } public void run(){//覆写run()方法 for(int i=0;i<30;i++){ System.out.println("Thread运行:"+this.name

2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller 模型-视图-控制器)是一种Web架构的模式,所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求. M

Python Django 多对多三种创建方式 form组件 cookie和session

一 表中多对多关系三种创建方式 以Book表和Author表多对多关系例 1.第一种方式:全自动(推荐使用):models.ManyToManyField(to='类名') 优点:不需要你手动创建第三张表 缺点:第三张表不是你手动创建的,字段是固定的无法拓展 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_place