GCD為Grand Central Dispatch的縮寫。 Grand Central Dispatch (GCD)是Apple開發的一個多核編程的較新的解決方法。在Mac OS X 10.6雪豹中首次推出,並在最近引入到了iOS4.0。 GCD是一個替代諸如NSThread等技術的很高效和強大的技術。GCD完全可以處理諸如數據鎖定和資源洩漏等復雜的異步編程問題。
GCD可以完成很多事情,但是這裡僅關注在iOS應用中實現多線程所需的一些基礎知識。 在開始之前,需要理解是要提供給GCD隊列的是代碼塊,用於在系統或者用戶創建的的隊列上調度運行。 聲明一個隊列
如下會返回一個用戶創建的隊列:
dispatch_queue_t myQueue = dispatch_queue_create("com.iphonedevblog.post", NULL);其中,第一個參數是標識隊列的,第二個參數是用來定義隊列的參數(目前不支持,因此傳入NULL)。
執行一個隊列
如下會異步執行傳入的代碼:
dispatch_async(myQueue, ^{ [self doSomething]; });其中,首先傳入之前創建的隊列,然後提供由隊列運行的代碼塊。
聲明並執行一個隊列
如果不需要保留要運行的隊列的引用,可以通過如下代碼實現之前的功能: dispatch_async(dispatch_queue_create ("com.iphonedevblog.post", NULL), ^{ [self doSomething]; }); 如果需要暫停一個隊列,可以調用如下代碼。暫停一個隊列會阻止和該隊列相關的所有代碼運行。 dispatch_suspend(myQueue);暫停一個隊列
如果暫停一個隊列不要忘記恢復。暫停和恢復的操作和內存管理中的retain和release類似。調用dispatch_suspend會增加暫停計數,而dispatch_resume則會減少。隊列只有在暫停計數變成零的情況下才開始運行。dispatch_resume(myQueue);恢復一個隊列 從隊列中在主線程運行代碼 有些操作無法在異步隊列運行,因此必須在主線程(每個應用都有一個)上運行。UI繪圖以及任何對NSNotificationCenter的調用必須在主線程長進行。在另一個隊列中訪問主線程並運行代碼的示例如下: dispatch_sync(dispatch_get_main_queue(), ^{ [self dismissLoginWindow]; });注意,dispatch_suspend (以及dispatch_resume)在主線程上不起作用。
使用GCD,可以讓你的程序不會失去響應. 多線程不容易使用,用了GCD,會讓它變得簡單。你無需專門進行線程管理, 很棒!
讓你的程序保持響應的原則:
1. 不要柱塞主線程
2. 把工作一到其他線程中做。
3. 做完後更新主線程的UI.
舉例說明:
沒有GCD的代碼:
- (void)addTweetWithMsg:(NSString*)msg url:(NSURL*)url {
// 在主線程調用。
DTweet *tw = [[DTweet alloc] initWithMsg:msg];
[tweets addTweet:tw display:YES];
tw.img =[imageCache getImgFromURL:url];//bottle neck
[tweets updateTweet:tw display:YES];
[tw release];
}
有GCD的代碼:
- (void)addTweetWithMsg:(NSString*)msg url:(NSURL*)url {
//在主線程調用。DTweet *tw = [[DTweet alloc] initWithMsg:msg];
[tweets addTweet:tw display:YES];
dispatch_async(image_queue, ^{
tw.img = [imageCache getImgFromURL:url];//放到一個異步隊列裡。
dispatch_async(main_queue, ^{
[tweets updateTweet:tw display:YES];//放到異步的主線程裡。
});
});
[tw release];
}
1. GCD is part of libSystem.dylib2. #include <dispatch/dispatch.h>
一》NSThread的方法:代碼如下:- (void)viewDidLoad
{
[superviewDidLoad];
NSThread*thread1=[[NSThreadalloc]initWithTarget:selfselector:@selector(print1)object:nil];
[thread1start];
NSThread*thread2=[[NSThreadalloc]initWithTarget:selfselector:@selector(print2)object:nil];
[thread2start];
}
-(void)print1{
for(inti=0; i<100; i++) {
NSLog(@"我是print1正在執行%d",i);
}
}
-(void)print2{
for(inti=0; i<100; i++) {
NSLog(@"print2正在執行%d",i);
}
}
二》NSInvocationOperation
的方法:代碼如下// NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(print1) object:@"1"];
// NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(print2) object:@"2"];//當然這裡可以用一個方法。
// NSOperationQueue *queue=[[NSOperationQueue alloc]init];
// [queue addOperation:operation1];
// [queue addOperation:operation2];
三》GCD
的方法:代碼如下dispatch_queue_tt1=dispatch_queue_create("1",NULL);
dispatch_queue_tt2=dispatch_queue_create("2",NULL);
dispatch_async(t1, ^{
[selfprint1];
});
dispatch_async(t2, ^{
[selfprint2];
});
Push的原理:
Push 的工作機制可以簡單的概括為下圖
圖中,Provider是指某個iPhone軟件的Push服務器,這篇文章我將使用.net作為Provider。 APNS 是Apple Push Notification Service(Apple Push服務器)的縮寫,是蘋果的服務器。
上圖可以分為三個階段。
第一階段:.net應用程序把要發送的消息、目的iPhone的標識打包,發給APNS。 第二階段:APNS在自身的已注冊Push服務的iPhone列表中,查找有相應標識的iPhone,並把消息發到iPhone。 第三階段:iPhone把發來的消息傳遞給相應的應用程序, 並且按照設定彈出Push通知。
看內存洩露時候:在搜索中搜索run 找到Run Static Snalyzer .