(一)NSThread
(二)Cocoa NSOperation
(三)GCD(全称:Grand Central Dispatch)
Grand Central dispatch(GCD)是Apple开发的一个多核编程的解决方案。在iOS4.0开始之后才能使用。GCD是一个替代NSThread, NSOperationQueue,NSInvocationOperation等技术的很高效强大的技术。
下面我用简单易于理解的代码实例来介绍NSThread在开发实践中的使用,具体使用时可以根据实际情况进行扩展:
一、NSThread的使用(基本已过时)
#import
#define kURL @"http://www.iyi8.com/uploadfile/2014/0506/20140506085929652.jpg"
@interface ViewController : UIViewController
@end
#import "ViewController.h"
@interface ViewController ()
{
UIImage *_image;
UIImageView *_imageView;
int _tickets;
int _count;
NSThread *_threadOne;
NSThread *_threadTwo;
NSThread *_threadThree;
NSCondition *_condition;
NSLock *_lock;
}
@end
@implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
NSLog(@"klfaklfa ------ - - ");
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 150)];
[self.view addSubview:_imageView];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_tickets = 200;
_count = 0;
_lock = [[NSLock alloc] init];
//锁对象
_condition = [[NSCondition alloc] init];
//线程1
_threadOne = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
_threadOne.name = @"thread-1";
[_threadOne start];
//线程2
_threadTwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
_threadTwo.name = @"thread-2";
[_threadTwo start];
//线程3
_threadThree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil];
_threadThree.name = @"thread-3";
[_threadThree start];
//如果没有线程同步的lock,物品售出数量就会出现重复导致数据竞争不同步问题.加上lock之后线程同步保证了数据的正确性。
[NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(downloadImage:) object:kURL];
[thread start];
}
/** 测试NSOperationQueue使用
*/
- (void)viewDidLoad
{
[super viewDidLoad];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(downloadImage:)
object:kURL];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
}
/** 测试GCD的dispatch_async使用*/
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL * url = [NSURL URLWithString:kURL];
NSData * data = [[NSData alloc]initWithContentsOfURL:url];
UIImage *image = [[UIImage alloc]initWithData:data];
if (data != nil) {
dispatch_async(dispatch_get_main_queue(), ^{
_imageView.image = image;
});
}
});
}
/** 测试GCD的dispatch_group_async使用*/
- (void)viewDidLoad
{
[super viewDidLoad];
//此方法可以实现监听一组任务是否完成,如果完成后通知其他操作(如界面更新),此方法在下载附件时挺有用,
//在搪行几个下载任务时,当下载完成后通过dispatch_group_notify通知主线程下载完成并更新相应界面
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:0.09];
NSLog(@"group1");
NSURL * url = [NSURL URLWithString:kURL];
NSData * data = [[NSData alloc]initWithContentsOfURL:url];
_image = [[UIImage alloc]initWithData:data];
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:0.09];
NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:0.09];
NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
_imageView.image = _image;
});
}
/** 测试GCD的dispatch_barrier_async使用*/
- (void)viewDidLoad
{
[super viewDidLoad];
//是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
dispatch_queue_t queue = dispatch_queue_create("gcd.devdiy.com", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"dispatch_async1");
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:4];
NSLog(@"dispatch_async2");
});
dispatch_barrier_async(queue, ^{
NSLog(@"dispatch_barrier_async");
[NSThread sleepForTimeInterval:4];
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"dispatch_async");
});
}
- (void)run3
{
while (true) {
[_condition lock];
[NSThread sleepForTimeInterval:3];
NSLog(@"当前物品名称:%d,售出数量:%d,线程名-=-==: %@", _tickets, _count, [[NSThread currentThread] name]);
[_condition signal];
[_condition unlock];
}
}
- (void)run
{
while (true) {
//上锁
[_lock lock];
if (_tickets > 0) {
[NSThread sleepForTimeInterval:0.09];
_count = 200 - _tickets;
NSLog(@"当前物品名称:%d,售出数量:%d,线程名: %@", _tickets, _count, [[NSThread currentThread] name]);
_tickets--;
}else{
break;
}
[_lock unlock];
}
}
/**
* @param string url
*/
- (void)downloadImage:(NSString *) url{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *image = [[UIImage alloc] initWithData:data];
if(image == nil){
[self updateUI:image];
}else{
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}
}
- (void)updateUI:(UIImage *)image
{
_imageView.image = image;
}
@end