1. GCD的API
/**
serial(連續的)
dispatch(分派)
serialDispatch 一個線程,同時執行的處理只能有一個,按順序執行
*/
void test_serialDispatch(){
dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
void(^blk_0)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_1)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_2)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_3)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_4)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_5)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_6)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_7)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
dispatch_async(mySerialDispatchQueue, blk_0);
dispatch_async(mySerialDispatchQueue, blk_1);
dispatch_async(mySerialDispatchQueue, blk_2);
dispatch_async(mySerialDispatchQueue, blk_3);
dispatch_async(mySerialDispatchQueue, blk_4);
dispatch_async(mySerialDispatchQueue, blk_5);
dispatch_async(mySerialDispatchQueue, blk_6);
dispatch_async(mySerialDispatchQueue, blk_7);
NSLog(@"%s,%d",__func__,__LINE__);
}
/**
concurrent(併發的,同時發生的)
concurrentDispatch 多個線程,並行執行
*/
void test_concurrentDispatch(){
dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.example.gcd.MyConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);
void(^blk_0)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_1)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_2)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_3)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_4)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_5)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_6)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
void(^blk_7)(void) = ^() {
NSLog(@"%s,%d",__func__,__LINE__);
};
dispatch_async(myConcurrentDispatchQueue, blk_0);
dispatch_async(myConcurrentDispatchQueue, blk_1);
dispatch_async(myConcurrentDispatchQueue, blk_2);
dispatch_async(myConcurrentDispatchQueue, blk_3);
dispatch_async(myConcurrentDispatchQueue, blk_4);
dispatch_async(myConcurrentDispatchQueue, blk_5);
dispatch_async(myConcurrentDispatchQueue, blk_6);
dispatch_async(myConcurrentDispatchQueue, blk_7);
NSLog(@"%s,%d",__func__,__LINE__);
}
void test_Main_Global_DispatchQueue(){
/**主線程*/
dispatch_queue_t mainDispachQueue = dispatch_get_main_queue();
/**高優先級*/
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
/**默認優先級*/
dispatch_queue_t globalDisaptchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/**低優先級*/
dispatch_queue_t globalDispatchQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
/**後臺優先級*/
dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
}
/**改變線程的優先級*/
void test_dispatch_set_target_queue(){
dispatch_queue_t myserialDispatchQueue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_set_target_queue(myserialDispatchQueue, globalDispatchQueueBackground);
}
void test_dispatch_after(){
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_USEC);
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(@"%s %d",__func__,__LINE__);
});
NSDate *date = [[NSDate alloc]initWithTimeIntervalSinceNow:5];
dispatch_after(getDispatchTimeByDate(date), dispatch_get_main_queue(), ^{
NSLog(@"%s %d",__func__,__LINE__);
});
NSLog(@"%s %d",__func__,__LINE__);
}
dispatch_time_t getDispatchTimeByDate(NSDate *date){
NSTimeInterval interval;
double second, subsecond;
struct timespec time;
dispatch_time_t milestone;
interval = [date timeIntervalSince1970];
subsecond = modf(interval, &second);
time.tv_sec = second;
time.tv_nsec = subsecond * NSEC_PER_SEC;
milestone = dispatch_walltime(&time, 0);
return milestone;
}
/**
無論向什麼樣的Dispatch Queue中追加處理,使用Dispatch Group都可監視這些處理執行的結束.一旦測試到所有處理執行結束,就可將結束的處理追加到Dispatch Queue中
*/
void test_Dispatch_Group(){
dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_async(queue, ^{
NSLog(@"%s %d",__func__,__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"%s %d",__func__,__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"%s %d",__func__,__LINE__);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"done");
});
}
void test_Dispatch_group_wait(){
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, ^{
NSLog(@"%s %d",__func__,__LINE__);
});
dispatch_group_async(group, queue, ^{
NSLog(@"%s %d",__func__,__LINE__);
});
dispatch_group_async(group, queue, ^{
sleep(4);
NSLog(@"%s %d",__func__,__LINE__);
});
long result = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 3ULL * NSEC_PER_SEC));
if (result == 0) {
NSLog(@"屬於Dispatch Group的全部處理執行結束");
}else{
NSLog(@"屬於Dispatch Group的某一個處理還在執行中");
}
}
/**
barrier(障礙)
應用於處理數據的讀寫問題
寫入處理不可以與其他的寫入處理以及包含讀取處理的其
他某些處理並行執行.
但是,讀取處理只是與讀取處理並行執行,那麼多個並行執
行就不會發生問題.
就是說:在寫入處理結束之前,讀取處理不可執行
*/
void test_dispatch_barrier_async(){
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.ForBarrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"reading data %d",__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"reading data %d",__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"reading data %d",__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"reading data %d",__LINE__);
});
dispatch_barrier_async(queue, ^{
NSLog(@"begin writing data %d",__LINE__);
sleep(4);
NSLog(@"end writing data %d",__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"reading data %d",__LINE__);
});
dispatch_async(queue, ^{
NSLog(@"reading data %d",__LINE__);
});
}
/**
asynchronous(異步的)
synchronous(同步的)
*/
void test_dispatch_sync(){
dispatch_queue_t queue = dispatch_queue_create("com.example.gcd.MySerialDispatchQueue", NULL);
dispatch_async(queue, ^{
dispatch_sync(queue, ^{
NSLog(@"Hell world");
});
});
}
void test_Dispatch_Apply(){
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSArray *array = @[@10, @9, @7, @6, @5, @4, @3, @2, @1];
dispatch_async(queue, ^{
dispatch_apply([array count], queue, ^(size_t index) {
NSLog(@"%zu %@",index, [array objectAtIndex:index]);
});
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"done");
});
});
}
/**
dispatch_supsend(queue)掛起
dispatch_resume(queue)回覆
*/
void test_dispatch_supsend_dispatch_resume(){
dispatch_queue_t queue = dispatch_queue_create("com.test.gcd", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
sleep(5);
NSLog(@"After 5 seconds...");
});
dispatch_async(queue, ^{
sleep(5);
NSLog(@"After 5 seconds again...");
});
NSLog(@"sleep 1 second...");
sleep(1);
NSLog(@"suspend...");
dispatch_suspend(queue);
NSLog(@"sleep 10 second...");
sleep(10);
NSLog(@"resume...");
}
/**
semaphore(信號)
*/
void test_dispatch_semaphore(){
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/**
生成dispatch_semaphore.並將計數初始值設定爲1
保持可訪問NSMutableArray類對象的線程同時只能有一個
*/
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i < 10000; i++) {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[array addObject:[NSNumber numberWithInt:i]];
dispatch_semaphore_signal(semaphore);
}
}
/**
保證函數在應用程序中只執行一次處理
生成單例對象使用
*/
void test_dispatch_once(){
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"初始化單例");
});
}
void test_dispatch_io(){
}
void test_timer(){
NSLog(@"%s",__func__);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 15ULL * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1ULL * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
NSLog(@"wakeup");
dispatch_source_cancel(timer);
});
dispatch_source_set_cancel_handler(timer, ^{
NSLog(@"cancel");
});
dispatch_resume(timer);
}
1. (void)countDownWithTime:(int)time
countDownBlock:(void (^)(int timeLeft))countDownBlock
endBlock:(void (^)())endBlock
{
__block int timeout = time;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(_timer, ^{
if(timeout<=0){
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
if (endBlock) {
endBlock();
}
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
timeout--;
if (countDownBlock) {
countDownBlock(timeout);
}
});
}
});
dispatch_resume(_timer);
}
2. NSThread
#pragma mark:NSThread
1. (void)testThread{
NSString *url = @"http://img4.imgtn.bdimg.com/it/u=2437762035,2994278153&fm=23&gp=0.jpg";
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downLoadData:) object:url];
[thread start];
}
2. (void)downLoadData:(NSString *)url{
NSLog(@"begin download.....");
for (int i = 0 ; i < 5; i++) {
sleep(1);
NSLog(@"download....%d%%",(i+1) * 20);
}
NSLog(@"finish download......");
[self performSelectorOnMainThread:@selector(refreshUI:) withObject:[NSData data] waitUntilDone:YES];
}
3. (void)refreshUI:(NSData *)data{
NSLog(@"%s",__func__);
}
4. (void)test_tickets{
tickets = 100;
count = 0;
theLock = [[NSLock alloc] init];
ticketsCondition = [[NSCondition alloc] init];
ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[ticketsThreadone setName:@"Thread-1"];
[ticketsThreadone start];
ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[ticketsThreadtwo setName:@"Thread-2"];
[ticketsThreadtwo start];
}
5. (void)run{
while (TRUE) {
[theLock lock];
if(tickets >= 0){
[NSThread sleepForTimeInterval:0.09];
count = 100 - tickets;
NSLog(@"當前票數是:%d,售出:%d,線程名:%@",tickets,count,[[NSThread currentThread] name]);
tickets--;
}else{
break;
}
[theLock unlock];
}
}
3. NSOperation
/**
使用 NSOperation的方式有兩種,
一種是用定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation。
另一種是繼承NSOperation
*/
-(void)testNSOperation{
NSString *url = @"http://img4.imgtn.bdimg.com/it/u=2437762035,2994278153&fm=23&gp=0.jpg";
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoadData:) object:url];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation];
}
相關鏈接:http://blog.jobbole.com/69019/