多线程文档格式.docx
《多线程文档格式.docx》由会员分享,可在线阅读,更多相关《多线程文档格式.docx(18页珍藏版)》请在冰点文库上搜索。
(id)argument
+(void)detachNewThreadSelector:
(SEL)aSelectortoTarget:
(id)aTargetwithObject:
(id)anArgument
第一个是实例方法,第二个是类方法
1、[NSThreaddetachNewThreadSelector:
@selector(doSomething:
)toTarget:
selfwithObject:
nil];
2、NSThread*myThread=[[NSThreadalloc]initWithTarget:
self
selector:
)
object:
[myThreadstart];
参数的意义:
selector:
线程执行的方法,这个selector只能有一个参数,而且不能有返回值。
target
:
selector消息发送的对象
argument:
传输给target的唯一参数,也可以是nil
第一种方式会直接创建线程并且开始运行线程,第二种方式是先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息
不显式创建线程的方法:
用NSObject的类方法
performSelectorInBackground:
withObject:
创建一个线程:
1
[ObjperformSelectorInBackground:
@selector(doSomething)withObject:
下载图片的例子:
新建singeViewapp
新建项目,并在xib文件上放置一个imageView控件。
按住control键拖到viewController.h文件中创建imageViewIBOutlet
ViewController.m中实现:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//
ViewController.m
NSThreadDemo
Createdbyrongfzhon12-9-23.
Copyright(c)2012年rongfzh.Allrightsreserved.
#import"
ViewController.h"
#definekURL@"
@interfaceViewController()
@end
@implementationViewController
-(void)downloadImage:
(NSString*)url{
NSData*data=[[NSDataalloc]initWithContentsOfURL:
[NSURLURLWithString:
url]];
UIImage*image=[[UIImagealloc]initWithData:
data];
if(image==nil){
}else{
[selfperformSelectorOnMainThread:
@selector(updateUI:
)withObject:
imagewaitUntilDone:
YES];
}
-(void)updateUI:
(UIImage*)image{
self.imageView.image=image;
-(void)viewDidLoad
{
[superviewDidLoad];
[NSThreaddetachNewThreadSelector:
@selector(downloadImage:
kURL];
NSThread*thread=[[NSThreadalloc]initWithTarget:
selfselector:
)object:
[threadstart];
-(void)didReceiveMemoryWarning
[superdidReceiveMemoryWarning];
//Disposeofanyresourcesthatcanberecreated.
@end
线程间通讯
线程下载完图片后怎么通知主线程更新界面呢?
performSelectorOnMainThread是NSObject的方法,除了可以更新主线程的数据外,还可以更新其他线程的比如:
performSelector:
onThread:
waitUntilDone:
运行下载图片:
线程同步
我们演示一个经典的卖票的例子来讲NSThread的线程同步:
#import<
UIKit/UIKit.h>
@classViewController;
@interfaceAppDelegate:
UIResponder<
UIApplicationDelegate>
inttickets;
intcount;
NSThread*ticketsThreadone;
NSThread*ticketsThreadtwo;
NSCondition*ticketsCondition;
NSLock*theLock;
@property(strong,nonatomic)UIWindow*window;
@property(strong,nonatomic)ViewController*viewController;
-(BOOL)application:
(UIApplication*)applicationdidFinishLaunchingWithOptions:
(NSDictionary*)launchOptions
tickets=100;
count=0;
theLock=[[NSLockalloc]init];
//锁对象
ticketsCondition=[[NSConditionalloc]init];
ticketsThreadone=[[NSThreadalloc]initWithTarget:
@selector(run)object:
[ticketsThreadonesetName:
@"
Thread-1"
];
[ticketsThreadonestart];
ticketsThreadtwo=[[NSThreadalloc]initWithTarget:
[ticketsThreadtwosetName:
Thread-2"
[ticketsThreadtwostart];
self.window=[[UIWindowalloc]initWithFrame:
[[UIScreenmainScreen]bounds]];
//Overridepointforcustomizationafterapplicationlaunch.
self.viewController=[[ViewControlleralloc]initWithNibName:
ViewController"
bundle:
self.window.rootViewController=self.viewController;
[self.windowmakeKeyAndVisible];
returnYES;
-(void)run{
while(TRUE){
//上锁
[ticketsConditionlock];
[theLocklock];
if(tickets>
=0){
[NSThreadsleepForTimeInterval:
0.09];
count=100-tickets;
NSLog(@"
当前票数是:
%d,售出:
%d,线程名:
%@"
tickets,count,[[NSThreadcurrentThread]name]);
tickets--;
break;
[theLockunlock];
[ticketsConditionunlock];
}
如果没有线程同步的lock,卖票数可能是-1.加上lock之后线程同步保证了数据的正确性。
上面例子我使用了两种锁,一种NSCondition,一种是:
NSLock。
NSCondition我已经注释了。
线程的顺序执行
他们都可以通过[ticketsConditionsignal];
发送信号的方式,在一个线程唤醒另外一个线程的等待。
比如:
47
48
49
50
51
52
53
54
55
56
57
58
59
60
AppDelegate.h"
@implementationAppDelegate
NSThread*ticketsThreadthree=[[NSThreadalloc]initWithTarget:
@selector(run3)object:
[ticketsThreadthreesetName:
Thread-3"
[ticketsThreadthreestart];
-(void)run3{
while(YES){
[ticketsConditionlock];
3];
[ticketsConditionsignal];
[ticketsConditionunlock];
[ticketsConditionwait];
wait是等待,我加了一个线程3去唤醒其他两个线程锁中的wait。
其他同步
我们可以使用指令@synchronized来简化NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。
-(void)doSomeThing:
(id)anObj
{
@synchronized(anObj)
//Everythingbetweenthebracesisprotectedbythe@synchronizeddirective.
}
还有其他的一些锁对象,比如:
循环锁NSRecursiveLock,条件锁NSConditionLock,分布式锁NSDistributedLock等等,可以自己看官方文档学习
NSThread下载图片的例子代码:
(二)CocoaNSOperation的使用
使用NSOperation的方式有两种,
一种是用定义好的两个子类:
另一种是继承NSOperation
如果你也熟悉Java,NSOperation就和java.lang.Runnable接口很相似。
和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。
相当与java中Runnalbe的Run方法。
然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。
NSInvocationOperation例子:
这里同样,我们实现一个下载图片的例子。
新建一个SingleViewapp,拖放一个ImageView控件到xib界面。
实现代码如下:
NSInvocationOperation*operation=[[NSInvocationOperationalloc]initWithTarget:
NSOperationQueue*queue=[[NSOperationQueuealloc]init];
[queueaddOperation:
operation];
//Doanyadditionalsetupafterloadingtheview,typi