IOS线程

一, iOS有三种多线程编程的技术,分别是:

1.、NSThread

2、Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue的使用

3、GCD  全称:Grand Central Dispatch( iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。

二,NSThread

1、

[NSThread detachNewThreadSelector:@selector(firstCounter)

toTarget:self

withObject:nil];

2、[self performSelectorInBackground:@selector(firstCounter) withObject:nil];

performSelectorInBackground方法为我们在后台创建了一个线程。这等同于 我们为 selectors 创建一个新的线程。 但是要记住,必须在调用的方法中加上自动释放池!

// 任务1

- (void) firstCounter{

@autoreleasepool {

// MyCode

}

}

来释放掉我们在操作过程中的内存!否则会发生内存泄漏!

对于使用线程的一些建议:

1.当我们需要中途停止线程时,我们不应该调用exit方法,而是调用cancel方法。因为,如果我们直接调用

exit方法的话,线程是直接退出,而没有机会去执行清理操作,可能会产生内存泄漏!

2.我们必须要清楚这么一个现象!

当线程在执行过程中,如果被sleepForTimeInterval后,线程将会被进入休眠。那么在它休眠期间又被cancel后,那么,事实上,线程在醒来后,任然会执行完它的操作

http://blog.sina.com.cn/s/blog_7b9d64af0101cajz.html

三,NSOperation

NSOperation是苹果封装的一套多线程的东西,不像GCD是纯C语言的,这个是OC的。但相比较之下GCD会更快一些,但本质上NSOPeration是多GCD的封装。

NSOperation与GCD的比较

GCD是基于c的底层api,NSOperation属于object-c类。ios首先引入的是NSOperation,IOS4之后引入了GCD和NSOperationQueue并且其内部是用gcd实现的。GCD优点:GCD主要与block结合使用。代码简洁高效。执行效率稍微高点。

NSOperation相对于GCD:

1,NSOperation拥有更多的函数可用,具体查看api。NSOperationQueue 是在GCD基础上实现的,只不过是GCD更高一层的抽象。

2,在NSOperationQueue中,可以建立各个NSOperation之间的依赖关系。

3,NSOperationQueue支持KVO。可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)

4,GCD 只支持FIFO 的队列,而NSOperationQueue可以调整队列的执行顺序(通过调整权重)。NSOperationQueue可以方便的管理并发、NSOperation之间的优先级。使用NSOperation的情况:各个操作之间有依赖关系、操作需要取消暂停、并发管理、控制操作之间优先级,限制同时能执行的线程数量.让线程在某时刻停止/继续等。使用GCD的情况:一般的需求很简单的多线程操作,用GCD都可以了,简单高效。从编程原则来说,一般我们需要尽可能的使用高等级、封装完美的API,在必须时才使用底层API。当需求简单,简洁的GCD或许是个更好的选择,而Operation queue 为我们提供能更多的选择

四 GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。

dispatch queue分成以下三种:

1)运行在主线程的Main queue,通过dispatch_get_main_queue获取。

/*!
* @function dispatch_get_main_queue
*
* @abstract
* Returns the default queue that is bound to the main thread.
*
* @discussion
* In order to invoke blocks submitted to the main queue, the application must
* call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main
* thread.
*
* @result
* Returns the main queue. This queue is created automatically on behalf of
* the main thread before main() is called.
*/
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
DISPATCH_EXPORT struct dispatch_queue_s _dispatch_main_q;
#define dispatch_get_main_queue() DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q)

可以看出,dispatch_get_main_queue也是一种dispatch_queue_t。

2)并行队列global dispatch queue,通过dispatch_get_global_queue获取,由系统创建三个不同优先级的dispatch queue。并行队列的执行顺序与其加入队列的顺序相同。

3)串行队列serial queues一般用于按顺序同步访问,可创建任意数量的串行队列,各个串行队列之间是并发的。

当想要任务按照某一个特定的顺序执行时,串行队列是很有用的。串行队列在同一个时间只执行一个任务。我们可以使用串行队列代替锁去保护共享的数据。和锁不同,一个串行队列可以保证任务在一个可预知的顺序下执行。

serial queues通过dispatch_queue_create创建,可以使用函数dispatch_retain和dispatch_release去增加或者减少引用计数。

GCD的用法

 //  后台执行:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });
 // 主线程执行:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });
 // 一次性执行:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });
 // 延迟2秒执行:
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });
 // 自定义dispatch_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{
   // your code
 });
 dispatch_release(urls_queue);
 // 合并汇总结果
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程一
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程二
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      // 汇总结果
 });

一个应用GCD的例子:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURL * url = [NSURL URLWithString:@"http://www.baidu.com"];
        NSError * error;
        NSString * data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
        if (data != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"call back, the data is: %@", data);
            });
        } else {
            NSLog(@"error when download:%@", error);
        }
    });

GCD的另一个用处是可以让程序在后台较长久的运行。

在没有使用GCD时,当app被按home键退出后,app仅有最多5秒钟的时候做一些保存或清理资源的工作。但是在使用GCD后,app最多有10分钟的时间在后台长久运行。这个时间可以用来做清理本地缓存,发送统计数据等工作。

让程序在后台长久运行的示例代码如下:

// AppDelegate.h文件
@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;

// AppDelegate.m文件
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self beingBackgroundUpdateTask];
    // 在这里加上你需要长久运行的代码
    [self endBackgroundUpdateTask];
}

- (void)beingBackgroundUpdateTask
{
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgroundUpdateTask];
    }];
}

- (void)endBackgroundUpdateTask
{
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}

时间: 2024-10-08 10:03:59

IOS线程的相关文章

iOS线程开发小结

/* 方法名决定是否开启新线程(async,sync),队列类型(全局队列,串行队列)决定开启多少条线程 1.快速线程调用 *开启后台线程执行任务 [self performSelectorInBackground:@selector(test) withObject:nil]; *回到主线程执行任务 [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES]; 2.GCD

iOS线程浅析

一.线程概述 1. iOS里面的线程按种类可分为同步线程和异步线程.同步线程指调用同步线程的地方必须等到同步线程执行完毕才可以继续向下执行.而调用异步线程的地方则在执行完调用异步线程的语句后就可以继续向下执行. 2.线程按调用方式又可以大致分为以下几种类型:NSObject.NSThread.NSOperation和GCD.NSObject和NSThread只能管理单个的线程,功能较简单,GCD和NSOperation则可以进行队列等复杂操作,且效率较高.其中GCD方式最为有效,NSOperat

IOS 线程处理 子线程

IOS 线程处理 子线程的启动与结束 技术交流新QQ群:414971585 IOS中,如果要在主线程中启动一个子线程,可以又两种方法: [NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil]; 这是在cocoa早期提供的方法,因此你可以在任何版本的ios和mac上调用此方法.在 OS X v10.5(or later)和IOS中,苹果又提供了一种方法,可以允许你获

ios线程总结(持续更新ing)

一.什么是线程: 1.1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程) 2.线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 3.1个线程中任务的执行是串行的,如果要在1各线程中执行多个任务,那么只能一个一个地按顺序执行这些任务,也就是说,在同一时间内,1个线程只能执行1个任务 二.什么是多线程 1.1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务 例:进程 ——>车间  ,线程——>车间工人 2.多线程的原理:同时间,CPU只能处理1条线程

iOS 线程锁同步机制

转载自 http://yulingtianxia.com/blog/2015/11/01/More-than-you-want-to-know-about-synchronized/ 如果你已经使用 Objective-C 编写过任何并发程序,那么想必是见过 @synchronized 这货了. @synchronized 结构所做的事情跟锁(lock)类似:它防止不同的线程同时执行同一段代码.但在某些情况下,相比于使用 NSLock 创建锁对象.加锁和解锁来说,@synchronized 用着

iOS线程加锁

// 加锁 @synchronized (self) { // 在同一时间,只能一个线程执行,但是很耗资源 } // 解锁 关于加锁,这里有一个东西.关于这个语法:@property.每次我们定义 一个属性的时候,会首当其冲的写上nonatomic,这是为什么?请看下面解说: nonatomic与atomic在@property中的不同: 都知道,这两个关键字代表的是同一个东西,只是代表的含义不同.是与线程有关的. nonatomic代表的是:线程是不安全的. atomic代表的是:线程是安全的

ios线程学习

1.什么是进程? 进程是指在系统中正在运行的一个应用程序.比如同时打开QQ.Xcode,系统就会分别启动2个进程.截图 2.什么是线程? 1).一个进程要想执行任务,必须得有线程(每一个进程至少要有一条线程) 2).线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行 3).一个线程中任务的执行是串行的.即如果要在1个线程中执行多个任务,那么只能一个一个的按顺序执行这些任务 3.什么是多线程? 1).一个线程中可以开启多条线程,每条线程可以并行执行不同的任务.比如同时开启三条线程分

iOS线程依赖

依赖的作用: 在iOS开发中,我们经常会用到一个线程需要等待另一个结束才能进行的需求,这种需求其实有很实用的解决办法.下面我将列举一些目前用到的方法: //需求:: 用NSOpertion和NSOpertionQueue处理A,B,C,D,E三个线程,要求执行完A,B,D,E后才能执行C,怎么做? // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 创建5个操作 NSOperation *a = [NSBlo

iOS线程安全问题

此文章将侧重于编写线程安全类和使用Grand Central Displatch(GCD)时的实用的技巧,设计模式,以及反模式. 线程安全 Apple的框架 首先让我们来看一下Apple的框架.一般情况下,除非提前声明,否则大多数类默认不是线程安全的.一些是我们所期望的,但是另一些却会相当有趣. 其中甚至有经验的iOS/Mac开发人员常会犯的错误是在后台线程中访问部分UIKit/AppKit.最容易犯的错误是在后台线程中对property赋值,比如图片,因为他们的内容是在后台从网络上获取的.Ap