+ detachNewThreadSelector:toTarget:withObject:
- initWithTarget:selector:object:
-performSelectorInBackground:withObject:
//方式1
NSThread * t1 = [[NSThread alloc]initWithTarget:self selector:@selector(doWork) object:nil];
[t1 start];
//方式2
[NSThread detachNewThreadSelector:@selector(doWork) toTarget:self withObject:nil];
//方式3
[self performSelectorInBackground:@selector(doWork) withObject:nil];
NSThread 对象的局限性:
-(void) fetchMoneyAndDecreBalance:(id) who
{
@synchronized(self){
NSLog(@"%@取钱:8000,取钱之前余额为:%d",who,self->balance);
[NSThread sleepForTimeInterval:0.1];
self->balance -= 8000;
[NSThread sleepForTimeInterval:0.1];
NSLog(@"%@取钱后余额为:%d",who,self->balance);
}
}
//
// ViewController.m
// NSThreadByStoryboard
//
// Created by 何瑾 on 15/1/13.
// Copyright (c) 2015年 e世雕龙. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;// 进度条
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark 使用线程的三种方式
- (IBAction)useThread:(id)sender {
// 方式一
NSThread *t1 = [[NSThread alloc]initWithTarget:self selector:@selector(doWork) object:nil];
// 必须手动启动线程
[t1 start];
// 方式二(不用手动启动线程,自动启动线程)
[NSThread detachNewThreadSelector:@selector(doWork) toTarget:self withObject:nil];
//方式三(不用手动启动线程,自动启动线程)
[self performSelectorInBackground:@selector(doWork) withObject:nil];
}
#pragma mark 线程完成的工作
- (void)doWork {
for (int i=1; i<=1000; i++) {
NSLog(@"%@%d",[NSThread currentThread],i);
}
}
#pragma mark 使用线程更新进度条
- (IBAction)updateProgressView:(id)sender {
// 创建线程
NSThread *t = [[NSThread alloc]initWithTarget:self selector:@selector(updateProgressViewUI) object:nil];
// 启动线程
[t start];
}
#pragma mark 更新进度条
- (void)updateProgressViewUI {
self.progressView.progress = 0;
for (int i=0; i<100; i++) {
// 让当前线程的runloop停止0.02秒
[NSThread sleepForTimeInterval:0.02f];
// 在主线程中更新UI
[self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES];
}
}
#pragma mark 更新UI
- (void)updateUI {
self.progressView.progress += 1.0/100;
}
#pragma mark 多线程取钱问题(线程同步问题)
- (IBAction)useThreadFetchMoney:(id)sender {
// 创建线程1
NSThread *husband = [[NSThread alloc]initWithTarget:self selector:@selector(fetchMoney:) object:@"大丈夫"];
// 启动线程1
[husband start];
// 创建线程2
NSThread *wife = [[NSThread alloc]initWithTarget:self selector:@selector(fetchMoney:) object:@"大老婆"];
// 启动线程2
[wife start];
}
#pragma mark 取钱方法
- (void)fetchMoney:(NSString *)who {
static int money = 10000;// 余额
// 线程同步前,结果很混乱
/*NSLog(@"%@开始取钱,取前余额:%d",who,money);
money -= 2000;
NSLog(@"%@取后余额:%d",who,money);*/
// 线程同步后,结果正常
@synchronized(self) {
NSLog(@"%@开始取钱,取前余额:%d",who,money);
money -= 2000;
NSLog(@"%@取后余额:%d",who,money);
}
}
@end
NSOperationQueue
// 创建操作对象
MyFetchMoneyOperation *husband = [MyFetchMoneyOperation new];
husband.who = @"大丈夫";
MyFetchMoneyOperation *wife = [MyFetchMoneyOperation new];
wife.who = @"大老婆";
// 多线程顺序执行操作队列,此句代码必须在往队列中加入操作之前
NSOperationQueue *queue = [NSOperationQueue new];
queue.maxConcurrentOperationCount = 1;
// 把所有操作放入操作队列中
[queue addOperation:husband];
[queue addOperation:wife];
//NSOperation对象是一个single-shot(一次性)对象,当它执行完一遍后,便不能再次使用,下面代码出错!
/*NSOperationQueue *queue2 = [[NSOperationQueue alloc]init];
[queue2 addOperation:husband];
[queue2 addOperation:wife];*/
BankAccount * account = [BankAccount new];
account.balance = 10000;
Fetcher * husband = [[Fetcher alloc]init];
Fetcher * wife = [[Fetcher alloc]init];
_husband.name = @"丈夫";
wife.name = @"妻子";
_husband.account = account;
wife.account = account;
NSOperationQueue * bankQueue = [NSOperationQueue new];
[bankQueue addOperation:_husband];
[bankQueue addOperation:wife];
//多线程顺序执行操作队列
bankQueue.maxConcurrentOperationCount = 1;
MyOperation *o1= [[[MyOperationalloc]init]autorelease];
o1.name = @"o1";
MyOperation *o2= [[[MyOperationalloc]init]autorelease];
o2.name = @"o2";
MyOperation *o3= [[[MyOperationalloc]init]autorelease];
o3.name = @"o3";
[o3 setQueuePriority:NSOperationQueuePriorityVeryHigh];
NSOperationQueue*queue = [[NSOperationQueuealloc]init];
[queue setMaxConcurrentOperationCount:1];
[queue addOperation:o1];
[queue addOperation:o2];
[queue addOperation:o3];
GrandCentralDispatch GCD
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
for(int i = 0;i < 100;i++){
[NSThread sleepForTimeInterval:0.02];
//在主线程中更新内容
dispatch_async(dispatch_get_main_queue(), ^{
self.progressView.progress += 0.01;
});
}
});
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
NSString * str1 = [self doWork1];
dispatch_async(dispatch_get_main_queue(), ^{
self.textView.text = [self.textView.text stringByAppendingFormat:@"%@\r\n",str1];
});
});
dispatch_async(queue, ^{
NSString * str2 = [self doWork2];
dispatch_async(dispatch_get_main_queue(), ^{
self.textView.text = [self.textView.text stringByAppendingFormat:@"%@\r\n",str2];
});
});
……
});
NSMutableString * totalString = [[NSMutableString alloc]initWithCapacity:10];
dispatch_group_t group =dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_async(group, queue, ^{
NSString * str1 = [self doWork1];
[totalString appendString:str1]; });
dispatch_group_async(group, queue, ^{
NSString * str2 = [self doWork2];
[totalString appendString:str2]; });
dispatch_group_async(group, queue, ^{
NSString * str3 = [self doWork3];
[totalString appendString:str3]; });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
self.textView.text = totalString;
});
GCD 与多核计算的关系
-(void)downloadImage:(NSIndexPath *)indexPath
{
@autoreleasepool {
……
UIImage * image = [UIImage imageWithData:data];
if(image != nil){
[self.imagesCache replaceObjectAtIndex:indexPath.row withObject:image];
}
//更新UI的代码须到主线程中执行
[self performSelectorOnMainThread:@selector(updateTableViewCellImage:) withObject:indexPath waitUntilDone:NO];
}
}