Objective-C 多线程

iOS有三种多线程技术:

  • 1.NSThread

    • 创建方式两种:

      • 1.实例方法:
      • - (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
      • 先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息
      • 2.类方法:
      • + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
      • 直接创建线程并开始运行线程
      • 使用范例:
        • [NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
        • NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
        • [myThread start];
      • 参数解释:
      • selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。
      • target :selector消息发送的对象
      • argument:传输给target的唯一参数,也可以是nil
      • 不显示创建线程的方法:
      • 调用NSObject的类方法performSelectorInBackground:withObject: 默认在子线程中执行
      • 示范:
        • [Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
      • 示范例子:(子线程异步下载,主线程UI更新)
#import "ViewController.h"
#define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"
@interface ViewController ()

@end

@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];

// [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];
[thread start];
}
-(void)downloadImage:(NSString *) url{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *image = [[UIImage alloc]initWithData:data];
if(image == nil){

}else{
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];//在主线程中执行(线程间通讯)
}
}
-(void)updateUI:(UIImage*) image{
self.imageView.image = image;
}
@end
  • 2.NSOperation

    • 用以封装执行程序中独立的工作单元,提供异步执行机制。
    • NSOperation类为抽象类,基于模版方法设计模式
    • Operations可以独立运行,也可以与Operation Queue协同运行。
    • 使用方式有两种:
      • 1.用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
      • NSInvocationOperation:
        • 创建方式:
        • NSInvocationOperation* operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(customTaskMethod:)object:params];
      • NSBlockOperation:
        • 创建方式:
        • NSBlockOperation* blockOperation = [NSBlockOperation blockOperationWithBlock: ^{
        • // to do the task.
        • }];
      • 在创建blockOperation后可以调用addExecutionBlock:方法添加更多的block
      • 示范例子:
#import "ViewController.h"
#define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self
selector:@selector(downloadImage:)
object:kURL];

NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation];
// Do any additional setup after loading the view, typically from a nib.
}

-(void)downloadImage:(NSString *)url{
NSLog(@"url:%@", url);
NSURL *nsUrl = [NSURL URLWithString:url];
NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];
UIImage * image = [[UIImage alloc]initWithData:data];
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}
-(void)updateUI:(UIImage*) image{
self.imageView.image = image;
}
      • 2.继承NSOperation

        • 1.提供一个自定义的初始化方法,在执行operation之前提供初始化流程,准备operation状态
        • 2.只需继承重写NSOperation的一个方法main
        • 3.然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它
        • 示范例子:
@interface MoveFileOperation : NSOperation

- (id)initWithSrcURL:(NSURL *)srcURL toDestinationURL:(NSURL*)desURL;

@end

// MoveFileOperation.m
@interface MoveFileOperation ()

@property (retain) NSURL *srcURL;

@property (retain) NSURL *desURL;

@end

@implementation MoveFileOperation

@synthesize rootURL, queue;

- (id)initWithSrcURL:(NSURL *)srcURL toDestinationURL:(NSURL*)desURL;
{
self = [super init];
if (self) {
self.srcURL = srcURL;
self.desURL = desURL;
}
return self;
}

- (void)main
{
if ([self isCancelled]){
return;
}
NSDirectoryEnumerator *itr =[[NSFileManager defaultManager] enumeratorAtURL:self.srcURL includingPropertiesForKeys:nil
options:(NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsPackageDescendants)
errorHandler:nil];
NSError *error = [NSError new];
for (NSURL *url in itr) {
if ([self isCancelled]) {//
break;
}else{
NSString *fileName = [url lastPathComponent];
NSURL *desFileURL = [self.desURL URLByAppendingPathComponent:fileName];
[[NSFileManager defaultManager] copyItemAtURL:url toURL:desFileURL error:&error];
}
}
}
        • 通过isCancelled方法对operation支持线程取消行为:
        • 常见的正确调用isCancelled的位置包括:
          • 1.在实际执行工作之前
          • 2.在每个循环的执行体中,如果一次执行体耗时很长可酌情添加调用次数
          • 3.程序相对容易终止的代码处。
        • 配置operation的依赖关系:
          • 调用addDependency: 方法可以建立两个operation对象间的依赖关系:
          • 这个单向关系表明当前operation对象只有在目标operation对象执行完成之后才能执行。
          • operation对象的依赖关系不限于同一个操作队列。
          • 有依赖关系的operation对象可以添加到不同的操作队列中。
          • 但是operation之间不能添加循环依赖关系。
        • 添加Completion Block:
          • 通过setCompletionBlock: 方法可以完成添加completion block的工作,可以在此处派发operation完成的消息。
        • 执行operation的方式:
          • 1 .将operation对象添加到操作队列NSOperatinQueue对象中:

            • NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
            • 1.// Add a single operation
            • [aQueue addOperation:anOp];
            • 2.// Add multiple operations
            • [aQueue addOperations:anArrayOfOps waitUntilFinished:NO];
            • 3.// Add a block
            • [aQueue addOperationWithBlock:^{
            • /* Do something. */
            • }];
            • NSOperationQueue设计上是用来并发执行operation,setMaxConcurrentOperationCount:方法可以设置操作队列并行执行的最大数量。
            • 需要设置operation间的依赖关系来保证它们的执行顺序是你想要的。
          • 2.手动执行operation:
            • 一个operation只有在其isReady方法返回YES时才被认为是可运行的。
            • isReady方法会被整合进NSOperation的依赖管理系统来保证operation的依赖状态。
            • 只有在依赖关系清楚后,operation才开始运行。
            • 手动执行operation时,必须调用其start方法。
        • 取消operation:
          • 一旦加入操作队列,操作队列就拥有了该operation,并且它不能被删除。
          • 调出operation的唯一方法是取消(cancel)它
          • 在一个operation上调用cancel可以取消其执行,在操作队列对象上调用cancelAllOperations 会取消所有operation。
          • operation的取消行为也会被认为是执行完毕(finished),依赖于它的其它operation对象会收到KVO通知来清除该依赖关系。
        • 等待operation结束:
          • 如果创建operation的进程需要处理operation的结果,可以使用NSOperation的 waitUntilFinished方法来阻塞代码直到operation完成(决不能在主线程上等待一个operation结束)
        • 挂起和回复队列:
          • 调用NSOperationQueue对象的setSuspended: 方法可以操作队列挂起。挂起队列不会阻碍当前正在执行中的operation,它只是阻止新的operation的执行。
  • 3.GCD
时间: 2024-08-27 07:20:29

Objective-C 多线程的相关文章

Objective-c——多线程开发第一天(pthread/NSThread)

一.为什么要使用多线程? 1.循环模拟耗时任务 1.同步执行 2.异步执行 (香烟编程小秘书) 3.进程 系统中正在运行的一个应用程序 每个进程之间是独立的, 均运行在其专用的且受保护的内存空间 通过活动监视器,可以查看mac系统中的开启进程 (外挂修改游戏进程中的数据,外挂用c汇编等底层) 4.线程 1个进程由一个或多个线程组成 是进程的基本执行单元(至少一个线程) 多线程: 1个进程可开启多个线程,多个线程可以“同时”执行不同任务 进程-公司,线程- 员工:老板:主线程 多线程可以提高程序的

objective c - 单例模式(多线程)

//基于gcd的单例模式 static Type *_instances; + (id)allocWithZone:(NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ _instances = [super allocWithZone:zone]; }); return _instances; } //创建一个获取单例的方法 + (Type *)sharedInstances { if(_i

iOS多线程编程指南(二)线程管理

当应用程序生成一个新的线程的时候,该线程变成应用程序进程空间内的一个实体.每个线程都拥有它自己的执行堆栈,由内核调度独立的运行时间片.一个线程可以和其他线程或其他进程通信,执行I/O操作,甚至执行任何你想要它完成的任务.因为它们处于相同的进程空间,所以一个独立应用程序里面的所有线程共享相同的虚拟内存空间,并且具有和进程相同的访问权限. 一.线程成本 多线程会占用你应用程序(和系统的)的内存使用和性能方面的资源.每个线程都需要分配一定的内核内存和应用程序内存空间的内存.管理你的线程和协调其调度所需

iOS开发核心语言Objective C —— 全部知识点总结

本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发人员,想进一步提升者.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基础.建议您先翻阅我之前分享的iOS开发分分钟搞定C语言系列,然后在開始Objective C语言的学习,假设您遇到问题也能够与我探讨.另外将无偿分享自己整理出来的大概400G iOS学习视频及学习资料,都是干货哦.能够新浪微博私信?关注极客James,期待与您的共同学习和探讨! ! 由于时间有限,每

iOS多线程到底不安全在哪里?

iOS多线程安全的概念在很多地方都会遇到,为什么不安全,不安全又该怎么去定义,其实是个值得深究的话题. 共享状态,多线程共同访问某个对象的property,在iOS编程里是很普遍的使用场景,我们就从Property的多线程安全说起. Property 当我们讨论property多线程安全的时候,很多人都知道给property加上atomic attribute之后,可以一定程度的保障多线程安全,类似: @property (atomic, strong) NSString* userName;事

从Objective-C到Swift 单例模式

在Objective-C中经常会用到单例模式.最常见的就是: [UIApplication sharedApplication].delegate 这里的sharedApplication就是一个返回单例的方法.所谓的单例模式也就是在整个APP.或者软件中只有这个类的这么一个对象.可以保存一些全局的设置等数据,达到单例对象变了整个app的全部设置都更新的效果. 忽略OC的代码,直接进入Swift代码. 第一种单例模式的实现: class Singleton1{ class var sharedI

Objective-C

1.Objective-C语言特性 2.static __block const 3.Object-C的内存管理 4.RunLoop 5.iOS消息传递机制 6.iOS程序生命周期 7.MVC设计模式MVVM 8.UIView CALayer Frame 与bounds 9.根类 NSObject 10.多线程简介 11.数据持久化 12.JSON和XML HTML 自定义报文 13.网络编程 HTTP TCP/IP Socket  ASI AFNetwork 14.AppStore上传 及远程

Objective - C中属性和点语法的使用

一.属性 属性是Objective—C 2.0定义的语法,为实例变量提供了setter.getter方法的默认实现能在一定程度上简化程序代码,并且增强实例变量的访问安全性 OC中的属性机制提供了便捷的设置和获取实例变量的方式,或者说属性提供了一个默认的设置器和访问器的实现:属性提供的方法是现实可配置的,属性的好处:相当于自己编写这一对方法,属性提供了一系列清晰分明的说明参数来定义设置器和访问器的行为,编译器可以根据你设置的说明参数为你生成相应的方法,减少你的代码量和维护工作量 设置器(sette

iOS核心语言Objective C语言 —— 内存管理

本分享是面向有意向从事iOS开发的伙伴以及苹果产品的发烧友们,或者已经从事了iOS的开发者,想进一步提升者.如果您对iOS开发有极高的兴趣,可以与我一起探讨iOS开发,一起学习,共同进步.如果您是零基础,建议您先翻阅我之前分享的iOS开发分分钟搞定C语言系列,然后在开始Objective C语言的学习,如果您遇到问题也可以与我探讨,另外将无偿分享自己整理出来的大概400G iOS学习视频及学习资料,都是干货哦!可以新浪微博私信?关注极客James,期待与您的共同学习和探讨!!由于时间有限,每天在

ios 多线程开发(一)简介

简介 线程是在一个程序中并发的执行代码的方法之一.虽然有一些新的技术(operations, GCD)提供了更先进高效的并发实现,OS X和iOS同时也提供了创建和维护线程的接口. 这里将要介绍线程相关的包以及如何使用他们.同时也会介绍程序中多线程代码的同步. 关于线程开发 多年以来,电脑的最大处理速度受制于单个处理器的处理速度.当单核处理器开始达到他们的上线时,芯片市场转向了多核的设计,这样电脑就可以同时处理多个任务了.OS X在处理系统任务时使用了这些优势,你自己的程序也可以使用这些优势.