一、线程的使用

以向网络请求一张图片为例

-(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)多线程开发的更多相关文章

  1. iOS多线程开发

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...

  2. iOS多线程开发资源抢夺和线程间的通讯问题

    说到多线程就不得不提多线程中的锁机制,多线程操作过程中往往多个线程是并发执行的,同一个资源可能被多个线程同时访问,造成资源抢夺,这个过程中如果没有锁机制往往会造成重大问题.举例来说,每年春节都是一票难 ...

  3. iOS多线程开发--NSThread NSOperation GCD

    多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...

  4. iOS多线程开发之离不开的GCD(上篇)

    一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的方法来进⾏并发程序编写.从基本功能上讲,GCD有点像NSOperatio ...

  5. ios多线程开发总结

    1>无论使用哪种方法进行多线程开发,每个线程启动后并不一定立即执行相应的操作,具体什么时候由系统调度(CPU空闲时就会执行). 2>更新UI应该在主线程(UI线程)中进行,并且推荐使用同步 ...

  6. ios多线程开发的常用三种方式

    1.NSThread 2.NSOperationQueue 3.GCD NSThread: 创建方式主要有两种: [NSThread detachNewThreadSelector:@selector ...

  7. ios 多线程开发(一)简介

    简介 线程是在一个程序中并发的执行代码的方法之一.虽然有一些新的技术(operations, GCD)提供了更先进高效的并发实现,OS X和iOS同时也提供了创建和维护线程的接口. 这里将要介绍线程相 ...

  8. ios 多线程开发(二)线程管理

    线程管理 iOS和OS X中每一个进程(或程序)由一个或多个线程组成.程序由一个运行main方法的线程开始,中间可以产生其他线程来执行一些指定的功能. 当程序产生一个新线程后,这个线程在程序进程空间内 ...

  9. ios 多线程开发(三)Run Loops

    Run loops是线程相关的一些基本东西.一个run loop是一个处理消息的循环.用来处理计划任务或者收到的事件.run loop的作用是在有事做的时候保持线程繁忙,没事的时候让线程挂起. Run ...

  10. ios多线程开发基础

    多线程编程:下载数据时,开辟子线程,减少阻塞时间,和主线程并发运行,提升用户体验 1.Thread 1>新建Thread对象,带一selector方法,调用start方法,开启子线程 2> ...

随机推荐

  1. HDU 5446 Unknown Treasure(Lucas定理+CRT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5446 [题目大意] 给出一个合数M的每一个质因子,同时给出n,m,求C(n,m)%M. [题解] ...

  2. Stitch Fix 融资1200万美元,又一个时尚创业的哈佛女MBA |华丽志

    Stitch Fix 融资1200万美元,又一个时尚创业的哈佛女MBA |华丽志 Stitch Fix 融资1200万美元,又一个时尚创业的哈佛女MBA

  3. 实习生的Django[1]

    尽管学期尚未结束,暑假尚未到来,可是大三的同学非常多已经和我一样開始实习或者实习一段时间了.我仅仅面试了一间数据挖掘的公司的研发部,还算顺利通过. 来这里实习后,由于网络原因,昨天没有刷题也没有写BL ...

  4. Android 之窗口小部件高级篇--App Widget 之 RemoteViews - 跨到对岸去

    在之前的一篇博文( Android 之窗口小部件详解--App Widge t)中,已经介绍了App Widget的基本用法和简单实例.这篇主要讲解 App Widget 的高级内容,即通过 Remo ...

  5. os基础

    命令:指计算机用户要求计算机系统为其工作的指示: 命令的表示形式: 1.字符形式: 2.菜单形式: 3.图形形式: 命令的使用方式:1. 脱机使用方式 off_line       2.联机使用方式  ...

  6. javascript操作HTML元素

    操作 HTML 元素 如需从 JavaScript 访问某个 HTML 元素,您可以使用 document.getElementById(id) 方法. 请使用 "id" 属性来标 ...

  7. 在unity 脚本中获取客户端的IP地址

    需要using System.Net.NetworkInformation;原理就是获取网卡的信息. //下面这段代码是我在百度贴吧找来的,经检验是正确的 string userIp = " ...

  8. JSP页面中包含文件

    在JSP中,主要有3种功能可以将外部内容包含到JSP文档中jsp:include动作. jsp:include动作允许我们在请求期间将其他页面的输出包含进来.它的主要优点是:在被包含的页面发生更改时, ...

  9. 最大流之sap算法

    若有向图G = (V , E)满足下列条件: 1.有且仅有一个顶点S,它的入度为 0 ,这个顶点称为源点. 2.有且仅有一个顶点T,它的出度为 0 ,这个顶点称为汇点. 3.每一条弧都有一个非负数,叫 ...

  10. YII框架下实现密码修改

    YII2 实现修改密码功能 主要难点: 1.密码加密 YII2对密码加密生成的结果是不同的,即用相同的初始密码在不同时间得到的加密结果不同,所以我们不能用常用的方法去验证密码是否正确(将密码加密后与数 ...