IOS多线程处理

IOS多线程处理

在Object-c中,常用的多线程处理类分别为NSThread和NSOperationQueue。使用这两个类处理多线程,让复杂的多线程处理变得简单高效。下面分别介绍。


一、NSThread类

苹果公司的Cocoa框架共支持三种多线程机制,分别为NSThread、GCD(Grand Central Dispatch)、Cocoa NSOperatio。NSThree是官方推荐的线程处理方式,它在处理机制上,需要开发者负责手动管理Thread的生命周期,包括子线程与主线程之间的同步等。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程 对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在 iOS 中我们可以使用多种形式的 thread。初次接触的读者也许会觉得生涩,但事实上NSThread类已经提供了完善的接口,在使用方式上并不会太难。使用NSTread管理线程,主要的步骤如下。

1)声明一个NSCondition同步锁;

2)声明若干个NSThread子线程;

3)指定NSThread子线程的目标指行方法(可以在构造函数中指定);

4)设置子线程的名称;

5)star启动子线程。

其中,子线程的执行方法一般只需要一个共同方法即可(可以通过线程名,分辨当前的执行线程)。下面通过代码演示NSThread类的使用。假设我们需要下载网络图片,在非异步形式的情况下,IOS界面必须等到图片下载完毕后,UI才会反应。这时利用多线程就可以达到异步下载的效果。

ViewController1.h

1
2
3
4
5
6
7
#import <UIKit/UIKit.h>
@interface ViewController1 : UIViewController{
     NSCondition *_condition;
     NSThread *_thread_1;
     NSThread *_thread_2;
}
@end


ViewController1.m

1
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//
//  ViewController1.m
//  Thread_demo
//
//  Created by MAC on 13-4-22.
//  Copyright (c) 2013年 李开涌. All rights reserved.
//
#import "ViewController1.h"
@interface ViewController1 ()
@end
@implementation ViewController1
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
     if  (self) {
         // Custom initialization
         self.title=@ "多线程NSThread" ;
     }
     return  self;
}
- ( void )viewDidLoad
{
     [super viewDidLoad];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
     //创建一个进程锁,实现线程同步
     _condition=[[NSCondition alloc] init];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
     //创建线程1
     _thread_1=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
     [_thread_1 setName:@ "thread_1" ];
     [_thread_1 start];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
     //创建线程2
     _thread_2=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
     [_thread_2 setName:@ "thread_2" ];
     [_thread_2 start];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
}
#pragma mark--线程执行方法
-( void )run{
     //进程上锁
     [_condition lock];
     NSLog(@ "运行的线程名:%@" ,[[NSThread currentThread]name]);
     if  ([[[NSThread currentThread]name] isEqualToString:@ "thread_1" ]) {
         NSLog(@ "111" );
         NSURL *imageUrl_1=[NSURL URLWithString:@ "http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg" ];
         NSData *data_1=[NSData dataWithContentsOfURL:imageUrl_1];
         UIImage *image_1=[UIImage imageWithData:data_1];
         UIImageView *imageView_1=[[UIImageView alloc] initWithImage:image_1];
         imageView_1.frame=CGRectMake(60, 20, 200, 200);
         [self.view addSubview:imageView_1];
         [imageView_1 release];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
     } else  if ([[[NSThread currentThread]name] isEqualToString:@ "thread_2" ]){
         NSLog(@ "222" );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
         NSURL *imageUrl_2=[NSURL URLWithString:@ "http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg" ];   
         NSData *data_2=[NSData dataWithContentsOfURL:imageUrl_2];
         UIImage *image_2=[UIImage imageWithData:data_2];
         UIImageView *imageView_2=[[UIImageView alloc] initWithImage:image_2];
         imageView_2.frame=CGRectMake(60, 250, 200, 200);
         [self.view addSubview:imageView_2];
         [imageView_2 release];
     }
     //解锁
     [_condition unlock];
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
}
-( void )dealloc{
     [_thread_1 release];
     [_thread_2 release];
     [_condition release];
     [super dealloc];
}
- ( void )didReceiveMemoryWarning
{
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
}
@end



二、NSOperationQueue类

如果需要让线程同时并行运行多个,可以将线程加入队列(Queue)中,NSOperationQueue类就是一个线程队列管理类,他提供了线程并行、队列的管理。可以认为NSOperationQueue就是一个线程管理器,通过addOperations方法,我们可以一次性把多个(数组形式)线程添加到队列中。同时,NSOperationQueue允许通过setMaxConcurrentOperationCount方法设置队列的并行(同一时间)运行数量。NSOperationQueue的使用步骤如下。

1)声明一个NSOperationQueue对象;

2)声明若干个NSInvocationOperation子线程对象,并指定回调方法;

3)将NSInvocationOperation子线程添加到数组;

4)把数组赋给NSOperationQueue类中的addOperations方法;

5) 实现回调方法;

6)在回调方法中实现performSelectorOnMainThread方法,更新主线程上的界面UI元素。


下面,使用NSOperationQueue类,实现前面NSThread类相同的功能(即下载图片)。代码如下。


ViewController2.m

1
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//
//  ViewController2.m
//  Thread_demo
//
//  Created by MAC on 13-4-22.
//  Copyright (c) 2013年 李开涌. All rights reserved.
//
#import "ViewController2.h"
@interface ViewController2 ()
@end
@implementation ViewController2
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
     if  (self) {
         // Custom initialization
         self.title=@ "线程队列" ;
     }
     return  self;
}
- ( void )viewDidLoad
{
     [super viewDidLoad];
     // 线程队列管理器,实现线程并行运行
     _opeartionQueue=[[NSOperationQueue alloc] init];
     //队列最大同时运行数量
     [_opeartionQueue setMaxConcurrentOperationCount:1];
                                                                                                                                                          
     tags=20;
     //创建线程1
     NSInvocationOperation *invocationOpearation_1=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@ "http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg" ] autorelease];
     //创建线程2
     NSInvocationOperation *invocationOpearation_2=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@ "http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg" ] autorelease];
                                                                                                                                                          
     NSArray *array=@[invocationOpearation_1,invocationOpearation_2];
     //把程序添加到管理器中
     [_opeartionQueue addOperations:array waitUntilFinished:YES];
}
-( void )run:(NSString *)imageStrinUrl{
     NSLog(@ "%@" ,[_opeartionQueue operations]);
     NSLog(@ "mainQueue%@" ,[NSOperationQueue mainQueue]);
     NSLog(@ "i==%i" ,tags);
     NSLog(@ "urlStr:%@" ,imageStrinUrl);
     NSURL *url=[NSURL URLWithString:imageStrinUrl];
     NSData *data=[NSData dataWithContentsOfURL:url];
     UIImage *image=[UIImage imageWithData:data];
     UIImageView *imageView=[[[UIImageView alloc] initWithImage:image]autorelease];
     imageView.frame=CGRectMake(60, tags, 200, 200);
     tags+=200;
     //通知主线程更新UI
     [self performSelectorOnMainThread:@selector(updateUI:) withObject:imageView waitUntilDone:NO];
                                                                                                                                                          
}
-( void )updateUI:(UIImageView *)imageView{
                                                                                                                                                          
     [self.view addSubview:imageView];
                                                                                                                                                          
}
- ( void )dealloc
{
     [_opeartionQueue release];
     [super dealloc];
}
- ( void )didReceiveMemoryWarning
{
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
}
@end


[self performSelectorOnMainThread:@selector(updateLabel:)withObject:updateData waitUntilDone:YES]; 该方法是一个主线程同步方法,不仅可以应用在NSOpeartionQueue中,同样还适用于NSThread类。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值