(IOS)多线程开发
一、线程的使用
以向网络请求一张图片为例
-(void)downURL:(NSURL *)aURL
{
NSData *d = [NSData dataWithContentsOfURL:aURL];
UIImage *img = [UIImage imageWithData:d];
//imgView.image = img;
// 切换回主线程执行UI的操作
[imgView performSelectorOnMainThread:@selector(setImage:) withObject:img waitUntilDone:NO];
}
方法1:系统后台执行
[self performSelectorInBackground:@selector(downURL:) withObject:url];
方法2:利用C级的NSThread执行
[NSThread detachNewThreadSelector:@selector(downURL:) toTarget:self withObject:url]; // 分派线程执行一个方法,静态方法创建了线程,并开始执行 NSThread *t1 = [[NSThread alloc] initWithTarget:self selector:@selector(downURL:) object:url];
[t1 start]; // 创建具体线程对象需要触发开始
方法3:利用OC级的NSOperation执行,此处使用的是NSOperation的子类NSInvocationOperation(或NSBlockOperation)去执行,因为NSOperation只是一个抽象类,不能直接实例化使用
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downURL:) object:url];
[op1 setQueuePriority:NSOperationQueuePriorityNormal]
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downURL:) object:url];
//[op1 start]; // 线程对象不放到队列中的话需要触发开始 queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = ; // 设置队列同时执行线程最大数
[queue addOperation:op1]; // 队列会自动打开线程
[queue addOperation:op2];
[op1 release];
[op2 release];
方法4:继承NSOperation自定义线程类,利用target-action机制
-(void)someMethod
{
BIDImageOperation *op = [[BIDImageOperation alloc] initWithTarget:self Selector:@selector(refreshUI:) URL:url1];
[op start];
// [op release];
} -(void)refreshUI:(UIImage *)aImg
{
[imgView performSelectorOnMainThread:@selector(setImage:) withObject:aImg waitUntilDone:NO];
}
using
#import <Foundation/Foundation.h> @interface BIDImageOperation : NSOperation
{
NSString *_imgURL;
id _target;
SEL _action;
} @property (nonatomic,retain) NSString *imgURL;
@property (nonatomic,assign) id target;
@property (nonatomic,assign) SEL action; -(id)initWithTarget:(id)aTarget Selector:(SEL)aSelector URL:(NSString *)aURL; @end ###################################### #import "BIDImageOperation.h" @implementation BIDImageOperation
@synthesize imgURL = _imgURL,target = _target,action = _action; -(id)initWithTarget:(id)aTarget Selector:(SEL)aSelector URL:(NSString *)aURL
{
if (self = [super init]) {
self.imgURL = aURL;
self.target = aTarget;
self.action = aSelector;
}
return self;
} -(void)main
{
if ([self isCancelled]) {
return;
} NSURL *url = [NSURL URLWithString:self.imgURL];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:data]; if ([self isCancelled]) {
return;
} [self.target performSelector:self.action withObject:img];
} @end
custom thread
二、线程安全
以一个售票服务的程序为例
1.锁
-(void)someMethod
{
NSThread *t1 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
t1.name = @"window1";
[t1 start]; NSThread *t2 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
t2.name = @"window2";
[t2 start];
//[NSThread detachNewThreadSelector:@selector(saleTicket) toTarget:self withObject:nil];
} -(void)saleTicket
{
while ()
{
[lock lock]; // 对可能出现互斥的变量设置部分进行锁定
if (count>)
{
count = - ticket;
NSLog(@"%@ 卖出:%d 剩余:%d",[NSThread currentThread].name,ticket,count);
ticket++;
} else {
[lock unlock];
break;
}
[lock unlock];
}
}
2.取消
[op cancel];并不能将线程取消掉,因为该方法是建议关闭而已,除非线程里的main或调用的方法中有对这个建议做接受处理,如下
if ([self isCancelled]) // or if([op isCancelled])
{
return;
}
在dealloc方法中,自定义线程类的成员变量都应该添加[op cancel];,队列则需要添加[queue cancelAllOperations];来停止退出线程。
(IOS)多线程开发的更多相关文章
- iOS多线程开发
概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...
- iOS多线程开发资源抢夺和线程间的通讯问题
说到多线程就不得不提多线程中的锁机制,多线程操作过程中往往多个线程是并发执行的,同一个资源可能被多个线程同时访问,造成资源抢夺,这个过程中如果没有锁机制往往会造成重大问题.举例来说,每年春节都是一票难 ...
- iOS多线程开发--NSThread NSOperation GCD
多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...
- iOS多线程开发之离不开的GCD(上篇)
一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的方法来进⾏并发程序编写.从基本功能上讲,GCD有点像NSOperatio ...
- ios多线程开发总结
1>无论使用哪种方法进行多线程开发,每个线程启动后并不一定立即执行相应的操作,具体什么时候由系统调度(CPU空闲时就会执行). 2>更新UI应该在主线程(UI线程)中进行,并且推荐使用同步 ...
- ios多线程开发的常用三种方式
1.NSThread 2.NSOperationQueue 3.GCD NSThread: 创建方式主要有两种: [NSThread detachNewThreadSelector:@selector ...
- ios 多线程开发(一)简介
简介 线程是在一个程序中并发的执行代码的方法之一.虽然有一些新的技术(operations, GCD)提供了更先进高效的并发实现,OS X和iOS同时也提供了创建和维护线程的接口. 这里将要介绍线程相 ...
- ios 多线程开发(二)线程管理
线程管理 iOS和OS X中每一个进程(或程序)由一个或多个线程组成.程序由一个运行main方法的线程开始,中间可以产生其他线程来执行一些指定的功能. 当程序产生一个新线程后,这个线程在程序进程空间内 ...
- ios 多线程开发(三)Run Loops
Run loops是线程相关的一些基本东西.一个run loop是一个处理消息的循环.用来处理计划任务或者收到的事件.run loop的作用是在有事做的时候保持线程繁忙,没事的时候让线程挂起. Run ...
- ios多线程开发基础
多线程编程:下载数据时,开辟子线程,减少阻塞时间,和主线程并发运行,提升用户体验 1.Thread 1>新建Thread对象,带一selector方法,调用start方法,开启子线程 2> ...
随机推荐
- 一步一步学数据结构之1--n(通用树)
今天来看大家介绍树,树是一种非线性的数据结构,树是由n个结点组成的有限集合,如果n=0,称为空树:如果n>0,则:有一个特定的称之为根的结点,它只有直接后继,但没有直接前驱:除根以外的其他结点划 ...
- OpenStack里的浮动ip
缺省情况下实例会被赋予固定ip,这时并不能保证实例会马上可以从外面访问到,一般来说需要配置防火墙来允许公共ip,然后建立一条NAT规则从公共ip到私有ip的映射.OpenStack引入了一个叫浮动ip ...
- Jquery 遍历数组之grep()方法介绍
grep()方法用于数组元素过滤筛选. grep(array,callback,boolean);方法参数介绍. array ---待处理数组 callback ---这个回调函数用来处理数组中 ...
- Javascript 递归函数
递归函数就是在函数内部调用它自己.在Javascript 中有很多写法,值得我们学习一下(Javascript太灵活了).还是用n的 阶乘 来写例子吧. 1. 首先,来看一个最普通 最正常的写法. f ...
- sql--关于exec和sp_execute
sql:exec与sp_excutesql的比较 exec与sp_execute都可以执行存储过程和批处理动态sql语句,以下所属均是关于批处理动态sql语句方面. 一.关于输入参数与输出参数 1.使 ...
- POJ 3461 Oulipo(模式串在主串中出现的次数)
题目链接:http://poj.org/problem?id=3461 题意:给你两个字符串word和text,求出word在text中出现的次数 思路:kmp算法的简单应用,遍历一遍text字符串即 ...
- Mybatis学习之JDBC缺陷
1.JDBC存在的问题 1.将sql语句硬编码到java代码中,如果修改sql语句,需要修改java代码,重新编译.系统可维护性不高. 设想如何解决?(将sql单独 配置在配置文件中) 2.数据库连接 ...
- [LeetCode]题解(python):108-Convert Sorted Array to Binary Search Tree
题目来源: https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ 题意分析: 给出一个排好序的数组,根据这 ...
- 使用RUBY生成二维码
二维码现在貌似已经成为一个项目必不可少的总分了,最近在做的微信项目,更是大大的依赖于二维码,微信公众平台提供的临时二维码,局限太多,只能带一个ID,做不了太多有意义的整个,因为我们很多的二维码是需要自 ...
- NuGet安装软件包故障解决
今晚在家工作,使用NuGet安装 Install-Package Microsoft.AspNet.Web.Optimization 时,一直提示无法连接到nuget.org. 搜索后,可使用如下方法 ...