IOS 多线程之GCD的详细操作

分类: ios开发   3985人阅读  评论(6)  收藏  举报

















实现代码:

CGDHelper

[cpp]  view plain copy
  1. /* 
  2.  *  Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。 
  3.  *  系统要求:iOS4.0以上。 
  4.  */  
  5.   
  6. #import <Foundation/Foundation.h>  
  7.    
  8. ///////////////////////////////////////     enum 声明     /////////////////////////////////////////////////  
  9.   
  10. //队列优先级  
  11. typedef enum  
  12. {  
  13.     GlobalQueuePriorityDefault = 0,  
  14.     GlobalQueuePriorityHigh = 2,  
  15.     GlobalQueuePriorityLow = -2,  
  16.     GlobalQueuePriorityBackground = INT16_MIN  
  17.       
  18. } GlobalQueuePriority;  
  19.   
  20. //阻塞、非阻塞  
  21. typedef enum  
  22. {  
  23.     PerformBlockFeatureChoke,  
  24.     PerformBlockFeatureUnchoke  
  25.       
  26. } PerformBlockFeature;  
  27.   
  28. //网络请求方法  
  29. typedef enum GCDHelperHttpRequestMethod  
  30. {  
  31.     GCDHelperHttpRequestMethodGET = 0,  
  32.     GCDHelperHttpRequestMethodPOST  
  33.       
  34. } GCDHelperHttpRequestMethod;  
  35.   
  36. ///////////////////////////////////////     Block 声明     /////////////////////////////////////////////////  
  37.   
  38. //返回值void  
  39. typedef     void (^GCDBlock)                         (void);  
  40. typedef     void (^GCDBlock1_Size_t)                 (size_t index);  
  41. typedef     void (^GCDBlock1_Int)                    (int index);  
  42. typedef     void (^GCDBlock1_Bool)                   (BOOL flag);  
  43. typedef     void (^GCDBlock1_Float)                  (float index);  
  44. typedef     void (^GCDBlock1_Obj)                    (id object);  
  45.   
  46. //返回值void,两个形式参数  
  47. typedef     void (^GCDBlock2)                        (id object1, size_t index);  
  48. typedef     void (^GCDBlock2_Obj_Int)                (id object1, int index);  
  49. typedef     void (^GCDBlock2_Obj_Obj)                (id object1, id object2);  
  50.   
  51. //有返回值  
  52. typedef     id   (^GCD_Obj_Block_Obj)                (id object);  
  53. typedef     id   (^GCD_Obj_Block_Void)               (void);  
  54.   
  55. typedef     void (^GCDHttpRequestBlock)              (NSURLResponse *response, NSError *error, NSData *data);  
  56.   
  57.   
  58. ///////////////////////////////////////     GCDHelper 声明     /////////////////////////////////////////////////  
  59.   
  60. @interface GCDHelper : NSObject  
  61.   
  62. /* 获取3种队列 */  
  63. + (dispatch_queue_t) gcdMainQueue;  
  64. + (dispatch_queue_t) gcdGlobalQueue:(GlobalQueuePriority) priority;  
  65. + (dispatch_queue_t) gcdCustomQueue:(NSString *) queueName;  
  66.   
  67. //后台执行  
  68. + (void) gcdPerformBlockAsynchronous:(GCDBlock) block;  
  69.   
  70. //后台获取数据后,回到主线程  
  71. + (void) gcdPerformBlockAsynchronous:(GCDBlock) blockAsyn  
  72.                          finishOnMainQueue:(GCDBlock) blockM;  
  73.   
  74.   
  75. /* 3种队列上执行Block  
  76.  * 
  77.  * 是否阻塞执行:(PerformBlockFeature) feature 
  78.  * 全局队列优先级:(GlobalQueuePriority) priority 
  79.  */  
  80. + (void) gcdPerformBlockOnMainQueue:(GCDBlock) block feature:(PerformBlockFeature) feature;  
  81.   
  82. + (void) gcdPerformBlockOnGlobalQueue:(GCDBlock) block  
  83.                               feature:(PerformBlockFeature) feature  
  84.                              priority:(GlobalQueuePriority) priority;  
  85.   
  86. + (void) gcdPerformBlockOnCustomQueue:(GCDBlock) block  
  87.                               feature:(PerformBlockFeature) feature  
  88.                                  name:(NSString *) queueName;  
  89.   
  90.   
  91. //延迟执行方法  
  92. + (void) gcdPerformBlock:(GCDBlock) block  
  93.                  onQueue:(dispatch_queue_t) queue  
  94.              delaySecond:(int64_t) second;  
  95.   
  96.   
  97. //只执行一次  
  98. + (void) gcdPerformBlockOnce:(GCDBlock) block;  
  99.   
  100. //并发  
  101. + (void) gcdBatchPerformBlocks:(NSArray *) blockArray finally:(GCDBlock) finallyBlock;  
  102.   
  103. + (void) gcdBatchPerformBlockWithData:(NSArray *) dataArray  
  104.           maxConcurrentOperationCount:(uint) count  
  105.                           handleBlock:(GCDBlock1_Obj) block  
  106.                               finally:(GCDBlock1_Obj) finallyBlock;  
  107.   
  108.   
  109.   
  110. @end  
  111.   
  112. ///////////////////////////////////////     图片下载     /////////////////////////////////////////////////  
  113.   
  114. @interface GCDHelper (ImageDownload)  
  115.   
  116. - (void) gcdImageWithURLString:(NSString *) URLString;  
  117. - (void) gcdImageWithURLString:(NSString *) URLString completion:(GCDBlock2_Obj_Obj) completion;  
  118.   
  119. @end  
  120.   
  121. ///////////////////////////////////////     网络请求     /////////////////////////////////////////////////  
  122.   
  123. GCDBlock1_Bool _netWorkBlock;  
  124. @interface GCDHelper (NetworkConnect)  
  125.   
  126. //网络连接判断、实时监控  
  127. - (void) gcdNetWorkGuarder:(NSString *) hostname withBlock:(GCDBlock1_Bool) block;  
  128.   
  129. @end  
  130.   
  131.   
  132. @interface GCDHelper (HttpRequest)  
  133.   
  134. //GCD请求网络(GET方式测试通过,POST方式测试未通过)  
  135. - (void) gcdHttpRequestWithURL:(NSString *) URLString  
  136.                     httpMethod:(GCDHelperHttpRequestMethod) method  
  137.                         params:(NSDictionary *) params  
  138.                        timeout:(NSTimeInterval) time  
  139.                        success:(GCDHttpRequestBlock) successBlock  
  140.                           fail:(GCDHttpRequestBlock) failBlock;  
  141.   
  142. @end  



[cpp]  view plain copy
  1. #import "GCDHelper.h"  
  2.   
  3. #import <SystemConfiguration/SystemConfiguration.h>  
  4.   
  5. #import <sys/socket.h>  
  6. #import <netinet/in.h>  
  7. #import <netinet6/in6.h>  
  8. #import <arpa/inet.h>  
  9. #import <ifaddrs.h>  
  10. #import <netdb.h>  
  11.   
  12. //Error  
  13. #define GCDHelperErrorURLISNULL   [NSError errorWithDomain:@"please setup GCDHelper‘s url or urlString" code:100 userInfo:nil]  
  14. #define GCDHelperErrorRequestISNULL  [NSError errorWithDomain:@"request can not be nil!" code:101 userInfo:nil]  
  15. #define GCDHelperErrorFileExist    [NSError errorWithDomain:@"File Exist!" code:102 userInfo:nil]  
  16. #define GCDHelperErrorCreateFail   [NSError errorWithDomain:@"Create File Fail!" code:103 userInfo:nil]  
  17.   
  18. //下载的临时文件的后缀  
  19. #define kTHDownLoadTask_TempSuffix  @".TempDownload"  
  20. //计算下载速度的取样时间  
  21. #define kTHDownLoadTimerInterval  2.0  
  22. //THDispatchQueue默认的并发数  
  23. #define kTHDispatchQueueDefaultConcurrentCount 10  
  24.   
  25. #define kDefaultTimeoutInterval  15  
  26.   
  27.   
  28. static NSString * const BOUNDRY        = @"--------------------------7d71a819230404";  
  29.   
  30.   
  31. @implementation GCDHelper  
  32.   
  33. - (void) dealloc  
  34. {  
  35.     [super dealloc];  
  36. }  
  37.   
  38. - (id) init  
  39. {  
  40.     if (self = [super init])  
  41.     {  
  42.     }  
  43.       
  44.     return self;  
  45. }  
  46.   
  47. #pragma mark -  
  48. #pragma mark 获取队列  
  49.   
  50. + (dispatch_queue_t) gcdMainQueue  
  51. {  
  52.     return dispatch_get_main_queue();  
  53. }  
  54.   
  55. + (dispatch_queue_t) gcdGlobalQueue:(GlobalQueuePriority) priority  
  56. {  
  57.     switch (priority)  
  58.     {  
  59.         case GlobalQueuePriorityDefault:  
  60.             return dispatch_get_global_queue(priority, 0);  
  61.             break;  
  62.         case GlobalQueuePriorityHigh:  
  63.             return dispatch_get_global_queue(priority, 0);  
  64.             break;  
  65.         case GlobalQueuePriorityLow:  
  66.             return dispatch_get_global_queue(priority, 0);  
  67.             break;  
  68.         case GlobalQueuePriorityBackground:  
  69.             return dispatch_get_global_queue(priority, 0);  
  70.             break;  
  71.               
  72.         default:  
  73.             return dispatch_get_global_queue(GlobalQueuePriorityDefault, 0);  
  74.             break;  
  75.     }  
  76. }  
  77.   
  78. + (dispatch_queue_t) gcdCustomQueue:(NSString *) queueName;  
  79. {  
  80.     return dispatch_queue_create([queueName UTF8String], NULL);  
  81. }  
  82.   
  83. #pragma mark -  
  84. #pragma mark 3种队列上执行Block  
  85.   
  86. + (void) gcdPerformBlockOnMainQueue:(GCDBlock) block feature:(PerformBlockFeature) feature  
  87. {  
  88.     switch (feature)  
  89.     {  
  90.         case PerformBlockFeatureChoke:  
  91.             dispatch_sync([GCDHelper gcdMainQueue], block);  
  92.             break;  
  93.               
  94.         case PerformBlockFeatureUnchoke:  
  95.             dispatch_async([GCDHelper gcdMainQueue], block);  
  96.             break;  
  97.               
  98.         default:  
  99.             dispatch_sync([GCDHelper gcdMainQueue], block);  
  100.             break;  
  101.     }  
  102. }  
  103.   
  104. + (void) gcdPerformBlockOnGlobalQueue:(GCDBlock) block feature:(PerformBlockFeature) feature priority:(GlobalQueuePriority) priority  
  105. {  
  106.     switch (feature)  
  107.     {  
  108.         case PerformBlockFeatureChoke:  
  109.             dispatch_sync([GCDHelper gcdGlobalQueue:priority], block);  
  110.             break;  
  111.               
  112.         case PerformBlockFeatureUnchoke:  
  113.             dispatch_async([GCDHelper gcdGlobalQueue:priority], block);  
  114.             break;  
  115.               
  116.         default:  
  117.             dispatch_sync([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], block);  
  118.             break;  
  119.     }  
  120. }  
  121.   
  122. + (void) gcdPerformBlockOnCustomQueue:(GCDBlock) block feature:(PerformBlockFeature) feature name:(NSString *) queueName  
  123. {  
  124.     switch (feature)  
  125.     {  
  126.         case PerformBlockFeatureChoke:  
  127.             dispatch_sync([GCDHelper gcdCustomQueue:queueName], block);  
  128.             break;  
  129.               
  130.         case PerformBlockFeatureUnchoke:  
  131.             dispatch_async([GCDHelper gcdCustomQueue:queueName], block);  
  132.             break;  
  133.               
  134.         default:  
  135.             dispatch_sync([GCDHelper gcdCustomQueue:@"com.GCDHelper.Queue"], block);  
  136.             break;  
  137.     }  
  138. }  
  139.   
  140. //后台执行  
  141. + (void) gcdPerformBlockAsynchronous:(GCDBlock) block  
  142. {  
  143.     [GCDHelper gcdPerformBlockOnGlobalQueue:block  
  144.                                     feature:PerformBlockFeatureUnchoke  
  145.                                    priority:GlobalQueuePriorityDefault];  
  146. }  
  147.   
  148. //后台获取数据后,回到主线程  
  149. + (void) gcdPerformBlockAsynchronous:(GCDBlock) blockAsyn  
  150.                    finishOnMainQueue:(GCDBlock) blockM  
  151. {  
  152.     dispatch_async([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], ^{  
  153.         blockAsyn();  
  154.         dispatch_async([GCDHelper gcdMainQueue], ^{  
  155.             blockM();  
  156.         });  
  157.     });  
  158. }  
  159.   
  160. #pragma mark -  
  161. #pragma mark 队列延迟时间执行方法  
  162. + (void) gcdPerformBlock:(GCDBlock) block onQueue:(dispatch_queue_t) queue delaySecond:(int64_t) second  
  163. {  
  164.     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, second * NSEC_PER_SEC);  
  165.     dispatch_after(popTime, queue, block);  
  166. }  
  167.   
  168. #pragma mark -  
  169. #pragma mark 只执行一次  
  170.   
  171. + (void) gcdPerformBlockOnce:(GCDBlock) block  
  172. {  
  173.     static dispatch_once_t onceToken;  
  174.     dispatch_once(&onceToken, block);  
  175. }  
  176.   
  177. #pragma mark -  
  178. #pragma mark 无序并发  
  179.   
  180. + (void) gcdBatchPerformBlocks:(NSArray *) blockArray finally:(GCDBlock) finallyBlock  
  181. {  
  182.     [blockArray retain];  
  183.       
  184.     dispatch_queue_t queue = [GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault];  
  185.     dispatch_group_t group = dispatch_group_create();  
  186.       
  187.     for(GCDBlock block in blockArray)  
  188.     {  
  189.         dispatch_group_async(group, queue, ^{  
  190.             block();  
  191.         });  
  192.     }  
  193.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  194.       
  195.     dispatch_async([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], ^{  
  196.         finallyBlock();  
  197.     });  
  198.       
  199.     dispatch_release(group);  
  200.       
  201.     [blockArray release];  
  202. }  
  203.   
  204. + (void) gcdBatchPerformBlockWithData:(NSArray *) dataArray  
  205.           maxConcurrentOperationCount:(uint) count  
  206.                           handleBlock:(GCDBlock1_Obj) block  
  207.                               finally:(GCDBlock1_Obj) finallyBlock  
  208. {  
  209.     [dataArray retain];  
  210.       
  211.     dispatch_queue_t queue = [GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault];  
  212.     dispatch_group_t group = dispatch_group_create();  
  213.     dispatch_semaphore_t semaphore = dispatch_semaphore_create(count);  
  214.     for(id obj in dataArray)  
  215.     {  
  216.         NSLog(@"并发中");  
  217.         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);  
  218.         dispatch_group_async(group, queue, ^{  
  219.             block(obj);  
  220.             dispatch_semaphore_signal(semaphore);  
  221.         });  
  222.     }  
  223.       
  224.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  225.     dispatch_group_notify(group, queue, ^{  
  226.         finallyBlock(dataArray);  
  227.     });  
  228.     dispatch_release(group);  
  229.       
  230.     [dataArray release];  
  231. }  
  232.   
  233.   
  234.   
  235. #pragma mark -  
  236. #pragma mark 图片下载  
  237.   
  238. - (void) gcdImageWithURLString:(NSString *) URLString  
  239. {  
  240.     [self gcdImageWithURLString:URLString completion:nil];  
  241. }  
  242.   
  243. - (void) gcdImageWithURLString:(NSString *) URLString completion:(GCDBlock2_Obj_Obj) completion  
  244. {  
  245.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  246.           
  247.         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  248.         [request setURL:[NSURL URLWithString:URLString]];  
  249.         [request setHTTPMethod:@"GET"];  
  250.         NSData *returnData = [NSURLConnection sendSynchronousRequest:request  
  251.                                                    returningResponse:nil  
  252.                                                                error:nil];  
  253.         [request release];  
  254.           
  255.         UIImage *image  = [UIImage imageWithData:returnData];  
  256.           
  257.         if (image)  
  258.         {  
  259.             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  260.                 completion(image, URLString);  
  261.             });  
  262.         } else  
  263.         {  
  264.             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  265.                 completion(image, URLString);  
  266.             });  
  267.         }  
  268.     });  
  269. }  
  270.   
  271. @end  
  272.   
  273.   
  274. #pragma mark -  
  275. #pragma mark 网络部分  
  276.   
  277. @implementation GCDHelper (NetworkConnect)  
  278.   
  279. - (BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags  
  280. {  
  281.     BOOL connectionUP = YES;  
  282.       
  283.     if(!(flags & kSCNetworkReachabilityFlagsReachable))  
  284.         connectionUP = NO;  
  285.       
  286.     if( (flags & (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)) == (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) )  
  287.         connectionUP = NO;  
  288.       
  289.     return connectionUP;  
  290. }  
  291.   
  292. -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags  
  293. {  
  294.     dispatch_async(dispatch_get_main_queue(), ^{  
  295.         _netWorkBlock([self isReachableWithFlags:flags]);  
  296.     });  
  297. }  
  298.   
  299. static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)  
  300. {  
  301.     @autoreleasepool  
  302.     {  
  303.         [(GCDHelper *)info reachabilityChanged:flags];  
  304.     }  
  305. }  
  306.   
  307. - (void) gcdNetWorkGuarder:(NSString *) hostname withBlock:(GCDBlock1_Bool) block  
  308. {  
  309.     _netWorkBlock = block;  
  310.       
  311.     SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);  
  312.     SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };  
  313.     dispatch_queue_t queue = dispatch_queue_create("com.myself.reachability", NULL);  
  314.     context.info = (void *)self;  
  315.     SCNetworkReachabilitySetCallback(ref, TMReachabilityCallback, &context);  
  316.     SCNetworkReachabilitySetDispatchQueue(ref, queue);  
  317. }  
  318.   
  319. @end  
  320.   
  321. @implementation GCDHelper(HttpRequest)  
  322.   
  323. - (void) startPOSTHTTPRequest:(NSString *) URLString  
  324.                        params:(NSDictionary *) params  
  325.                       timeout:(NSTimeInterval) time  
  326.                       success:(GCDHttpRequestBlock) successBlock  
  327.                          fail:(GCDHttpRequestBlock) failBlock  
  328. {  
  329.     [params retain];  
  330.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  331.           
  332.         __block NSURLResponse  *response = nil;  
  333.         __block NSError *error = nil;  
  334.         __block NSData *receiveData = nil;  
  335.           
  336.         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  337.           
  338.         [request setURL:[NSURL URLWithString:[URLString lowercaseString]]];  
  339.         [request setHTTPMethod:@"POST"];  
  340.         [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  341.         [request setTimeoutInterval:time];  
  342.           
  343.         if (!request)  
  344.         {  
  345.             NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"发送请求失败", @"errorKey", nil];  
  346.             error = [NSError errorWithDomain:@"www.myself.com" code:100 userInfo:errorInfo];  
  347.               
  348.             dispatch_async(dispatch_get_main_queue(), ^{  
  349.                 successBlock(response, error, receiveData);  
  350.             });  
  351.               
  352.             return;  
  353.         }  
  354.           
  355.         if (params != nil)  
  356.         {  
  357.             [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", BOUNDRY]  
  358.            forHTTPHeaderField:@"Content-Type"];  
  359.               
  360.             int len=512;  
  361.             NSMutableData *postData =[NSMutableData dataWithCapacity:len];  
  362.             [postData appendData:[[NSString stringWithFormat:@"--%@/r/n", BOUNDRY]  
  363.                                   dataUsingEncoding:NSUTF8StringEncoding]];  
  364.             int i=0;  
  365.             int cnt = [params count];  
  366.               
  367.             for (NSString *key in [params allKeys])  
  368.             {  
  369.                 // NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"/r/n/r/n", key];  
  370.                 [postData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"/r/n/r/n", key] dataUsingEncoding:NSUTF8StringEncoding]];  
  371.                   
  372.                 [postData  appendData: [[NSString stringWithFormat:@"%@",[params objectForKey:key]]  
  373.                                         dataUsingEncoding:NSUTF8StringEncoding]];  
  374.                 if(i != cnt - 1)  
  375.                 {  
  376.                     [postData appendData:[[NSString stringWithFormat:@"/r/n--%@/r/n", BOUNDRY]  
  377.                                           dataUsingEncoding:NSUTF8StringEncoding]];  
  378.                 }  
  379.                 i++ ;  
  380.             }  
  381.             [postData  appendData:[[NSString stringWithFormat:@"/r/n--%@--/r/n", BOUNDRY]  
  382.                                    dataUsingEncoding:NSUTF8StringEncoding]];  
  383.               
  384.             [request  setHTTPBody:postData];  
  385.         }  
  386.           
  387.         receiveData = [[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] retain];  
  388.         if (!error)  
  389.         {  
  390.             dispatch_async(dispatch_get_main_queue(), ^{  
  391.                 successBlock(response, nil, receiveData);  
  392.             });  
  393.         }  
  394.         else  
  395.         {  
  396.             dispatch_async(dispatch_get_main_queue(), ^{  
  397.                 successBlock(response, error, receiveData);  
  398.             });  
  399.         }  
  400.           
  401.         [request release];  
  402.     });  
  403.       
  404.     [params release];  
  405. }  
  406.   
  407. - (void) startGETHTTPRequest:(NSString *) URLString  
  408.                       params:(NSDictionary *) params  
  409.                      timeout:(NSTimeInterval) time  
  410.                      success:(GCDHttpRequestBlock) successBlock  
  411.                         fail:(GCDHttpRequestBlock) failBlock  
  412. {  
  413.     [params retain];  
  414.       
  415.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  416.         __block NSURLResponse  *response = nil;  
  417.         __block NSError *error = nil;  
  418.         __block NSData *receiveData = nil;  
  419.           
  420.         NSMutableString *paramsString = [[NSMutableString alloc] init];  
  421.         for(NSString *key in params)  
  422.         {  
  423.             [paramsString appendFormat:@"&%@=%@", key, [params objectForKey:key]];  
  424.         }  
  425.         NSString *requestString = [[NSString alloc] initWithFormat:@"%@%@", URLString, paramsString];  
  426.         NSURL *reqUrl = [[NSURL alloc] initWithString:requestString];  
  427.           
  428.         [paramsString release];  
  429.         [requestString release];  
  430.           
  431.         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  432.           
  433.         [request setURL:reqUrl];  
  434.         [request setHTTPMethod:@"GET"];  
  435.         [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  436.         [request setTimeoutInterval:time];  
  437.           
  438.         [reqUrl release];  
  439.       
  440.         if (request)  
  441.         {  
  442.             receiveData = [[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] retain];  
  443.         }  
  444.           
  445.         if (!error)  
  446.         {  
  447.             dispatch_async(dispatch_get_main_queue(), ^{  
  448.                 successBlock(response, nil, receiveData);  
  449.             });  
  450.         }  
  451.         else  
  452.         {  
  453.             dispatch_async(dispatch_get_main_queue(), ^{  
  454.                 successBlock(response, error, receiveData);  
  455.             });  
  456.         }  
  457.           
  458.         [request release];  
  459.     });  
  460.       
  461.     [params release];  
  462. }  
  463.   
  464. - (void) gcdHttpRequestWithURL:(NSString *) URLString  
  465.                     httpMethod:(GCDHelperHttpRequestMethod) method  
  466.                         params:(NSDictionary *) params  
  467.                        timeout:(NSTimeInterval) time  
  468.                        success:(GCDHttpRequestBlock) successBlock  
  469.                           fail:(GCDHttpRequestBlock) failBlock  
  470. {  
  471.     switch (method)  
  472.     {  
  473.         case GCDHelperHttpRequestMethodGET:  
  474.         {  
  475.             [self startGETHTTPRequest:URLString params:params timeout:time success:successBlock fail:failBlock];  
  476.             break;  
  477.         }  
  478.         case GCDHelperHttpRequestMethodPOST:  
  479.         {  
  480.             [self startPOSTHTTPRequest:URLString params:params timeout:time success:successBlock fail:failBlock];  
  481.             break;  
  482.         }  
  483.   
  484.         default:  
  485.             break;  
  486.     }  
  487. }  
  488.   
  489. @end  




用法举例:

一、基本概念举例:

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface BaseViewController : UIViewController  
  4. {  
  5.     IBOutlet UITextField *field1;  
  6.     IBOutlet UITextField *field2;  
  7.     IBOutlet UITextField *field3;  
  8.       
  9.     IBOutlet UITextField *textField;  
  10.       
  11.     dispatch_queue_t queue;  
  12. }  
  13.   
  14. - (IBAction) calculate:(id)sender;  
  15. - (IBAction) operationQueue:(id)sender;  
  16. - (IBAction) gcd:(id)sender;  
  17.   
  18. - (IBAction) notchoke:(id)sender;  
  19. - (IBAction) choke:(id)sender;  
  20.   
  21. - (IBAction) getUIData:(id)sender;  
  22.   
  23.   
  24. - (IBAction)startQueue:(id)sender;  
  25. - (IBAction)suspendQueue:(id)sender;  
  26. - (IBAction)resumeQueue:(id)sender;  
  27.   
  28. @end  

[cpp]  view plain copy
  1. #import "BaseViewController.h"  
  2.   
  3. @implementation BaseViewController  
  4.   
  5. - (void) dealloc  
  6. {  
  7.     dispatch_release(queue);  
  8.       
  9.     [super dealloc];  
  10. }  
  11.   
  12. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  13. {  
  14.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  15.     if (self) {  
  16.         queue = dispatch_queue_create("sss", NULL);  
  17.     }  
  18.     return self;  
  19. }  
  20.   
  21. - (void)viewDidLoad  
  22. {  
  23.     [super viewDidLoad];  
  24.     // Do any additional setup after loading the view from its nib.  
  25. }  
  26.   
  27. - (void) longTask:(id) sender  
  28. {  
  29.     NSMutableArray *arr = [NSMutableArray array];  
  30.     for (int i = 0; i < 1000; i++) {  
  31.           
  32.         [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  33.         NSLog(@"longTask:%d", i);  
  34.     }  
  35. }  
  36.   
  37. - (void) longTaskOther:(id) sender  
  38. {  
  39.     NSMutableArray *arr = [NSMutableArray array];  
  40.     for (int i = 0; i < 10000; i++) {  
  41.           
  42.         [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  43.         NSLog(@"longTaskOther:%d", i);  
  44.     }  
  45. }  
  46.   
  47. - (IBAction) calculate:(id)sender  
  48. {  
  49.     field3.text = [NSString stringWithFormat:@"%f", [field1.text floatValue] - [field2.text floatValue]];  
  50. }  
  51. - (IBAction) operationQueue:(id)sender;  
  52. {  
  53.     NSOperationQueue *aqueue = [NSOperationQueue new];  
  54.     NSInvocationOperation *operation = [[NSInvocationOperation alloc]  
  55.                                         initWithTarget:self  
  56.                                         selector:@selector(longTask:)  
  57.                                         object:nil];  
  58.     NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]  
  59.                                         initWithTarget:self  
  60.                                         selector:@selector(longTaskOther:)  
  61.                                         object:nil];  
  62.       
  63.   
  64.     [aqueue addOperation:operation];  
  65.     [aqueue addOperation:operation1];  
  66.       
  67.     [operation release];  
  68.     [operation1 release];  
  69. }  
  70. - (IBAction) gcd:(id)sender  //3.192999  
  71. {  
  72.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  73.         NSMutableArray *arr = [NSMutableArray array];  
  74.         for (int i = 0; i < 1000; i++) {  
  75.               
  76.             [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  77.             NSLog(@"longTask:%d", i);  
  78.         }  
  79.     }];  
  80.       
  81.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  82.         NSMutableArray *arr = [NSMutableArray array];  
  83.         for (int i = 0; i < 10000; i++) {  
  84.               
  85.             [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  86.             NSLog(@"longTaskOther:%d", i);  
  87.         }  
  88.     }];  
  89. }  
  90.   
  91. //////////////////////////////////////////////////////  
  92.   
  93. - (IBAction)notchoke:(id)sender  
  94. {  
  95.     dispatch_async(dispatch_get_main_queue(), ^{  
  96.         NSLog(@"qqq");  
  97.     });  
  98.   
  99.     NSLog(@"不阻塞");  
  100. }  
  101.   
  102.   
  103. //Calls to dispatch_sync() targeting the current queue will result  
  104. //* in dead-lock. Use of dispatch_sync() is also subject to the same  
  105. //* multi-party dead-lock problems that may result from the use of a mutex.  
  106. //* Use of dispatch_async() is preferred.  
  107. //在当前队列上调用dispatch_sync() 会导致死锁。调用dispatch_sync(),并使用mutex 经常会导致多方死锁问题。  
  108. - (IBAction) choke:(id)sender  
  109. {  
  110.     dispatch_queue_t exampleQueue;  
  111.       
  112.     int i = 3;  
  113.     switch (i) {  
  114.         case 0:  
  115.             exampleQueue = dispatch_get_global_queue(0, 0);  
  116.             break;  
  117.         case 1:  
  118.             exampleQueue = dispatch_queue_create("com.abc.xxx", NULL);  
  119.             break;  
  120.         case 2:  
  121.             exampleQueue = dispatch_get_current_queue();  
  122.             break;  
  123.         case 3:  
  124.             exampleQueue = dispatch_get_main_queue();  
  125.             break;  
  126.               
  127.         default:  
  128.             exampleQueue = dispatch_get_global_queue(0, 0);  
  129.             break;  
  130.     }  
  131.       
  132.     dispatch_sync( exampleQueue,^{  
  133.         [self longTask:nil];  
  134.     });  
  135.       
  136.     NSLog(@"task finish");  
  137. }  
  138.   
  139. - (IBAction) getUIData:(id)sender  
  140. {  
  141.     dispatch_async(dispatch_get_global_queue(0, 0), ^{  
  142.           
  143.         __block NSString *stringValue;  
  144.         dispatch_sync(dispatch_get_main_queue(), ^{  
  145.             stringValue = [textField.text copy];  
  146.         });  
  147.           
  148.         [stringValue retain];  
  149.           
  150.         NSLog(@"stringValue:%@", stringValue);  
  151.     });  
  152. }  
  153.   
  154.   
  155.   
  156. //一个要注意的地方是,dispatch queue的挂起是block粒度的。换句话说,挂起一个queue并不会将当前正在执行的block挂起。它会允许当前执行的block执行完毕,然后后续的block不再会被执行,直至queue被恢复。  
  157. //还有一个注意点:从man页上得来的:如果你挂起了一个queue或者source,那么销毁它之前,必须先对其进行恢复。  
  158. - (IBAction)startQueue:(id)sender  
  159. {  
  160.     dispatch_async(queue, ^{  
  161.         for (int i = 0; i < 10000; i++) {  
  162.             NSLog(@"taskA");  
  163.         }  
  164.     });  
  165.       
  166.     dispatch_async(queue, ^{  
  167.         for (int i = 0; i < 10000; i++) {  
  168.             NSLog(@"taskB");  
  169.         }  
  170.     });  
  171.       
  172.     dispatch_async(queue, ^{  
  173.         for (int i = 0; i < 10000; i++) {  
  174.             NSLog(@"taskC");  
  175.         }  
  176.     });  
  177. }  
  178. - (IBAction)suspendQueue:(id)sender  
  179. {  
  180.     NSLog(@"Queue suspend");  
  181.     dispatch_suspend(queue);  
  182.   
  183. }  
  184. - (IBAction)resumeQueue:(id)sender  
  185. {  
  186.     NSLog(@"Queue resume");  
  187.     dispatch_resume(queue);  
  188.   
  189. }  

二、基本用法举例

例子1:

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface OneViewController : UIViewController  
  4.   
  5.   
  6. //无序并发  
  7. - (IBAction)selector0:(id)sender;  
  8.   
  9. //无序并发处理数据  
  10. - (IBAction)selector100:(id)sender;  
  11.   
  12. //执行一次  
  13. - (IBAction)selector1:(id)sender;  
  14.   
  15. //异步/后台执行  
  16. - (IBAction)selector2:(id)sender;  
  17.   
  18. //后台执行,然后返回主线程  
  19. - (IBAction)selector3:(id)sender;  
  20.   
  21. //三种队列执行  
  22. - (IBAction)selector4:(UISegmentedControl *)sender;  
  23.   
  24. //延迟执行  
  25. - (IBAction)selector5:(id)sender;  
  26.   
  27. @end  

[cpp]  view plain copy
  1. #import "OneViewController.h"  
  2.   
  3. @interface OneViewController ()  
  4.   
  5. @end  
  6.   
  7. @implementation OneViewController  
  8.   
  9. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  10. {  
  11.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  12.     if (self) {  
  13.         // Custom initialization  
  14.     }  
  15.     return self;  
  16. }  
  17.   
  18. - (void)viewDidLoad  
  19. {  
  20.     [super viewDidLoad];  
  21. }  
  22.   
  23. - (NSMutableArray *) getBlockArray  
  24. {  
  25.     NSMutableArray *arr = [[NSMutableArray array] retain];  
  26.       
  27.     GCDBlock b0 = ^{ NSLog(@"无序并发: 0"); sleep(3); }; [arr addObject:b0];  
  28.     GCDBlock b1 = ^{ NSLog(@"无序并发: 1"); }; [arr addObject:b1];  
  29.     GCDBlock b2 = ^{ NSLog(@"无序并发: 2"); }; [arr addObject:b2];  
  30.     GCDBlock b3 = ^{ NSLog(@"无序并发: 3"); }; [arr addObject:b3];  
  31.     GCDBlock b4 = ^{ NSLog(@"无序并发: 4"); }; [arr addObject:b4];  
  32.     GCDBlock b5 = ^{ NSLog(@"无序并发: 5"); }; [arr addObject:b5];  
  33.     GCDBlock b6 = ^{ NSLog(@"无序并发: 6"); }; [arr addObject:b6];  
  34.     GCDBlock b7 = ^{ NSLog(@"无序并发: 7"); }; [arr addObject:b7];  
  35.     GCDBlock b8 = ^{ NSLog(@"无序并发: 8"); }; [arr addObject:b8];  
  36.     GCDBlock b9 = ^{ NSLog(@"无序并发: 9"); }; [arr addObject:b9];  
  37.     GCDBlock b10 = ^{ NSLog(@"无序并发: 10"); }; [arr addObject:b10];  
  38.     GCDBlock b11 = ^{ NSLog(@"无序并发: 11"); }; [arr addObject:b11];  
  39.     GCDBlock b12 = ^{ NSLog(@"无序并发: 12"); }; [arr addObject:b12];  
  40.     GCDBlock b13 = ^{ NSLog(@"无序并发: 13"); }; [arr addObject:b13];  
  41.     GCDBlock b14 = ^{ NSLog(@"无序并发: 14"); }; [arr addObject:b14];  
  42.     GCDBlock b15 = ^{ NSLog(@"无序并发: 15"); }; [arr addObject:b15];  
  43.       
  44.     return arr;  
  45. }  
  46.   
  47. //无序并发  
  48. - (IBAction)selector0:(id)sender  
  49. {  
  50.     [GCDHelper gcdBatchPerformBlocks:[self getBlockArray] finally:^{  
  51.         NSLog(@"一组有序并发完成");  
  52.     }];  
  53.       
  54. //    NSLog(@"一组无序并发完成");  
  55. }  
  56.   
  57.   
  58. - (IBAction)selector100:(id)sender  
  59. {  
  60.     NSMutableArray *arr = [NSMutableArray array];  
  61.     for (int i = 0; i < 100; i++) {  
  62.         [arr addObject:[NSMutableArray array]];  
  63.     }  
  64.       
  65.     __block int i = 0;  
  66.     [GCDHelper gcdBatchPerformBlockWithData:arr maxConcurrentOperationCount:10 handleBlock:^(id object) {  
  67.           
  68.         sleep(1);  
  69.         NSMutableArray *arr = (NSMutableArray *)object;  
  70.         [arr addObject:@(i)];  
  71.         i++;  
  72.     } finally:^(id object) {  
  73.         NSLog(@"arr:%@", object);  
  74.     }];  
  75. }  
  76.   
  77. - (IBAction)selector1:(id)sender  
  78. {  
  79.     [GCDHelper gcdPerformBlockOnce:^{  
  80.         NSLog(@"别想让我执行第二次");  
  81.     }];  
  82.     NSLog(@"不执行~");  
  83. }  
  84.   
  85. //异步/后台执行  
  86. - (IBAction)selector2:(id)sender  
  87. {  
  88.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  89.         sleep(3);  
  90.          NSLog(@"全局队列执行完成");  
  91.     }];  
  92.     NSLog(@"全局队列执行,不影响主队列");  
  93. }  
  94.   
  95. //后台执行,然后返回主线程  
  96. - (IBAction)selector3:(id)sender  
  97. {  
  98.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  99.          
  100.         for (int i = 0; i< 10; i++)  
  101.         {  
  102.             NSLog(@"全局队列执行: %d", i);  
  103.         }  
  104.           
  105.     } finishOnMainQueue:^{  
  106.         NSLog(@"回到主队列");  
  107.     }];  
  108. }  
  109.   
  110. //三种队列执行  
  111. - (IBAction)selector4:(UISegmentedControl *)sender  
  112. {  
  113.     switch (sender.selectedSegmentIndex) {  
  114.         case 0:  
  115.         {  
  116.             [GCDHelper gcdPerformBlockOnMainQueue:^{  
  117.                 NSLog(@"主队列执行");  
  118.             } feature:PerformBlockFeatureUnchoke];  
  119.             break;  
  120.         }  
  121.         case 1:  
  122.         {  
  123.             [GCDHelper gcdPerformBlockOnGlobalQueue:^{  
  124.                 NSLog(@"全局队列执行");  
  125.             } feature:PerformBlockFeatureUnchoke priority:GlobalQueuePriorityDefault];  
  126.             break;  
  127.         }  
  128.         case 2:  
  129.         {  
  130.             [GCDHelper gcdPerformBlockOnCustomQueue:^{  
  131.                 NSLog(@"自创建队列执行");  
  132.             } feature:PerformBlockFeatureUnchoke name:@"com.abc.bcd"];  
  133.             break;  
  134.         }  
  135.               
  136.         default:  
  137.             break;  
  138.     }  
  139. }  
  140.   
  141. //延迟执行  
  142. - (IBAction)selector5:(id)sender  
  143. {  
  144.     NSLog(@"延迟 2s 执行");  
  145.     [GCDHelper gcdPerformBlock:^{  
  146.         NSLog(@"执行完毕");  
  147.     } onQueue:[GCDHelper gcdMainQueue] delaySecond:2];  
  148. }  
  149.   
  150. @end  

例子2:

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface MulthreadConcurrentVC : UIViewController  
  4.   
  5.   
  6. @end  

[cpp]  view plain copy
  1. #import "MulthreadConcurrentVC.h"  
  2.   
  3. /* 
  4.   
  5.  如何在GCD中快速的控制并发呢?答案就是 
  6.  dispatch_semaphore,对经常做unix开发的人来讲,我所介绍的内容可能就显得非常入门级了,信号量在他们的多线程开发中再平常不过了。 
  7.  在GCD中有三个函数是semaphore的操作,分别是: 
  8.  dispatch_semaphore_create          创建一个semaphore 
  9.  dispatch_semaphore_signal          发送一个信号 
  10.  dispatch_semaphore_wait              等待信号 
  11.  简单的介绍一下这三个函数,第一个函数有一个整形的参数,我们可以理解为信号的总量,dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量减少1,根据这样的原理,我们便可以快速的创建一个并发控制。 
  12.   
  13.  */  
  14.   
  15.   
  16. /* 
  17.   
  18. 简单的介绍一下这一段代码,创建了一个初使值为10的semaphore,每一次for循环都会创建一个新的线程,线程结束的时候会发送一个信号,线程创建之前会信号等待,所以当同时创建了10个线程之后,for循环就会阻塞,等待有线程结束之后会增加一个信号才继续执行,如此就形成了对并发的控制,如上就是一个并发数为10的一个线程队列。 
  19.   
  20. */  
  21.   
  22. @implementation MulthreadConcurrentVC  
  23.   
  24. - (void) loadView  
  25. {  
  26.     [super loadView];  
  27. }  
  28.   
  29. - (void)aSelector:(id)sender  
  30. {  
  31.     dispatch_group_t group = dispatch_group_create();  
  32.     dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);  
  33.     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  34.     for (int i = 0; i < 100; i++)  
  35.     {  
  36.         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);  
  37.         dispatch_group_async(group, queue, ^{  
  38.             NSLog(@"%i",i);  
  39.             sleep(2);  
  40.             dispatch_semaphore_signal(semaphore);  
  41.         });  
  42.     }  
  43.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  44.     dispatch_release(group);  
  45.     dispatch_release(semaphore);  
  46. }  
  47.   
  48. - (void)viewDidLoad  
  49. {  
  50.     [super viewDidLoad];  
  51.       
  52.     UIButton *bt = [UIButton buttonWithType:UIButtonTypeRoundedRect];  
  53.     bt.frame = CGRectMake(100, 100, 120, 120);  
  54.     [bt addTarget:self action:@selector(aSelector:) forControlEvents:UIControlEventTouchUpInside];  
  55.     [self.view addSubview:bt];  
  56. }  

三、GCD实际应用举例

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. #import "GCDHelper.h"  
  4.   
  5. @interface TableViewController : UITableViewController  
  6.   
  7. @end  

[cpp]  view plain copy
  1. #import "TableViewController.h"  
  2. #import "CustomCell.h"  
  3. #import <objc/runtime.h>  
  4.   
  5. static char * const kIndexPathAssociationKey = "JK_indexPath";  
  6.   
  7. @interface TableViewController ()  
  8.   
  9. @end  
  10.   
  11. @implementation TableViewController  
  12.   
  13. - (id)initWithStyle:(UITableViewStyle)style  
  14. {  
  15.     self = [super initWithStyle:style];  
  16.     if (self) {  
  17.         // Custom initialization  
  18.     }  
  19.     return self;  
  20. }  
  21.   
  22. - (void)viewDidLoad  
  23. {  
  24.     [super viewDidLoad];  
  25.   
  26.     self.clearsSelectionOnViewWillAppear = NO;  
  27.     self.navigationItem.rightBarButtonItem = self.editButtonItem;  
  28. }  
  29.   
  30. - (void)didReceiveMemoryWarning  
  31. {  
  32.     [super didReceiveMemoryWarning];  
  33.     // Dispose of any resources that can be recreated.  
  34. }  
  35.   
  36. #pragma mark - Table view data source  
  37.   
  38. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  
  39. {  
  40.     return 1;  
  41. }  
  42.   
  43. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
  44. {  
  45.     return 100;  
  46. }  
  47.   
  48. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  49. {  
  50.     static NSString *CellIdentifier = @"Cell";  
  51.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  52.       
  53.     if (cell == nil) {  
  54.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];  
  55.         UIImageView *im = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];  
  56.         im.tag = 10;  
  57.         [cell addSubview:im];  
  58.         [im release];  
  59.     }  
  60.       
  61.     return cell;  
  62. }  
  63.   
  64. - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath  
  65. {  
  66. //    http://localhost:8888/Imgs/img0.png  
  67. //    http://theme.blogcn.com/wp-content/themes/coffee-desk/images/rsscoffee.PNG  
  68.       
  69.     NSString *imgURLStr = nil;  
  70.     if ((indexPath.row % 2) == 0)  
  71.     {  
  72.         imgURLStr = @"http://localhost:8888/Imgs/img0.png";  
  73.     } else  
  74.     {  
  75.         imgURLStr = @"http://localhost:8888/Imgs/img1.png";  
  76.     }  
  77.       
  78.     GCDHelper *hp = [GCDHelper new];  
  79.     [hp gcdImageWithURLString:imgURLStr  
  80.                    completion:^(id object1, id object2) {  
  81.                       
  82.                        dispatch_async(dispatch_get_main_queue(), ^{  
  83.                            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];  
  84.                            [(UIImageView *)[cell viewWithTag:10] setImage:(UIImage *)object1];  
  85.                        });  
  86.                    }];  
  87. }  
  88.   
  89. #pragma mark - Table view delegate  
  90.   
  91. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  92. {  
  93. }  
  94.   
  95. #pragma mark -  
  96. #pragma mark - cell重用  
  97.   
  98. - (void)tableViewCellIsPreparingForReuse:(NSNotification *)notification  
  99. {  
  100.     if ([[notification object] isKindOfClass:[CustomCell class]]) {  
  101.         CustomCell *cell = (CustomCell *)[notification object];  
  102.           
  103.         objc_setAssociatedObject(cell,  
  104.                                  kIndexPathAssociationKey,  
  105.                                  nil,  
  106.                                  OBJC_ASSOCIATION_RETAIN);  
  107.           
  108.         [[cell imageView] setImage:nil];  
  109.     }  
  110. }  
  111.   
  112. @end  

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. extern NSString * const kJKPrepareForReuseNotification;  
  4.   
  5. @interface CustomCell : UITableViewCell  
  6.   
  7. @end  

[cpp]  view plain copy
  1. #import "CustomCell.h"  
  2.   
  3. NSString * const kJKPrepareForReuseNotification = @"JKCallbacksTableViewCell_PrepareForReuse";  
  4.   
  5. @implementation CustomCell  
  6.   
  7. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier  
  8. {  
  9.     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];  
  10.     if (self) {  
  11.         //如果cell 的图片发生改变,当cell重用的时候,刷新图片  
  12.           
  13.         [[self imageView] addObserver:self  
  14.                            forKeyPath:@"image"  
  15.                               options:NSKeyValueObservingOptionOld  
  16.                               context:NULL];  
  17.     }  
  18.     return self;  
  19. }  
  20.   
  21. - (void)observeValueForKeyPath:(NSString *)keyPath  
  22.                       ofObject:(id)object  
  23.                         change:(NSDictionary *)change  
  24.                        context:(void *)context  
  25. {  
  26.     NSLog(@"observeValueForKeyPath");  
  27.       
  28.     if (object == [self imageView] &&  
  29.         [keyPath isEqualToString:@"image"] &&  
  30.         ([change objectForKey:NSKeyValueChangeOldKey] == nil ||  
  31.          [change objectForKey:NSKeyValueChangeOldKey] == [NSNull null]))  
  32.     {  
  33.         [self setNeedsLayout];  
  34.     }  
  35. }  
  36.   
  37. - (void)prepareForReuse  
  38. {  
  39.     [[NSNotificationCenter defaultCenter] postNotificationName:kJKPrepareForReuseNotification  
  40.                                                         object:self];  
  41.       
  42.     [super prepareForReuse];  
  43. }  
  44.   
  45. @end  

----------------------------------------------

[cpp]  view plain copy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface NetGuarder : NSObject  
  4.   
  5. + (NetGuarder *) shareNetGuarder;  
  6.   
  7. @end  

[cpp]  view plain copy
  1. #import "NetGuarder.h"  
  2.   
  3. @implementation NetGuarder  
  4.   
  5. static NetGuarder *guarder = nil;  
  6.   
  7. + (void) getNetConnectMsg  
  8. {  
  9.     GCDHelper *hp = [GCDHelper new];  
  10.     [hp gcdNetWorkGuarder:@"www.baidu.com" withBlock:^(BOOL flag) {  
  11.         if (flag)  
  12.         {  
  13.             NSLog(@"Net connect");  
  14.         } else  
  15.         {  
  16.             NSLog(@"Net not connect");  
  17.         }  
  18.     }];  
  19. }  
  20.   
  21. + (NetGuarder *) shareNetGuarder  
  22. {  
  23.     static dispatch_once_t predicate;  
  24.     dispatch_once(&predicate, ^{  
  25.           
  26.         NSLog(@"单例创建");  
  27.         guarder = [[self alloc] init];  
  28.           
  29.         [NetGuarder getNetConnectMsg];  
  30.     });  
  31.       
  32.     return guarder;  
  33. }  
  34.   
  35. @end  

-------------------------------------------

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface URLConViewController : UIViewController <NSURLConnectionDataDelegate>  
  4. {  
  5.     IBOutlet UISegmentedControl *segment;  
  6.     IBOutlet UILabel *label;  
  7. }  
  8.   
  9. @end  

[cpp]  view plain copy
  1. #import "URLConViewController.h"  
  2.   
  3. typedef struct _INT  
  4. {  
  5.     int t1;  
  6.       
  7. }INT_STRUCT;  
  8.   
  9. @interface URLConViewController ()  
  10. {  
  11.     NSMutableData *receivedData;  
  12.     BOOL finished;  
  13. }  
  14.   
  15. @end  
  16.   
  17. @implementation URLConViewController  
  18.   
  19. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  20. {  
  21.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  22.     if (self)  
  23.     {  
  24.         receivedData = [[NSMutableData data] retain];  
  25.     }  
  26.     return self;  
  27. }  
  28.   
  29. - (void)viewDidLoad  
  30. {  
  31.     [super viewDidLoad];  
  32. }  
  33.   
  34. - (void)didReceiveMemoryWarning  
  35. {  
  36.     [super didReceiveMemoryWarning];  
  37. }  
  38.   
  39. - (void) cleanText  
  40. {  
  41.     label.text = @"";  
  42. }  
  43.   
  44. - (IBAction)segmentAction:(UISegmentedControl *)sender  
  45. {  
  46.     switch (sender.selectedSegmentIndex) {  
  47.         case 0:  
  48.         {  
  49.             [self sendRequestSync];  
  50.             break;  
  51.         }  
  52.         case 1:  
  53.         {  
  54.             [self sendRequestAsync];  
  55.             break;  
  56.         }  
  57.         case 2:  
  58.         {  
  59.             [self sendRequestAsyncOther];  
  60.             break;  
  61.         }  
  62.         case 3:  
  63.         {  
  64.             [self gcdRequest];  
  65.             break;  
  66.         }  
  67.               
  68.         default:  
  69.             break;  
  70.     }  
  71. }  
  72.   
  73. #pragma mark -  
  74. #pragma mark  GCDRequest  
  75.   
  76. - (void) gcdRequest  
  77. {  
  78.     GCDHelper *hp = [GCDHelper new];  
  79.       
  80.     [hp gcdHttpRequestWithURL:@"http://localhost:8888/test.php"  
  81.                    httpMethod:GCDHelperHttpRequestMethodGET  
  82.                        params:[NSDictionary dictionary]  
  83.                       timeout:5.0f  
  84.                       success:^(NSURLResponse *response, NSError *error, NSData *data) {  
  85.                           if (data && (!error))  
  86.                           {  
  87.                               label.text = [[data objectFromJSONData] description];  
  88.                           }  
  89.                             
  90.                       }  
  91.                          fail:^(NSURLResponse *response, NSError *error, NSData *data) {  
  92.                              if (error)  
  93.                              {  
  94.                                  label.text = [error description];  
  95.                              }  
  96.                          }];  
  97. }  
  98.   
  99. #pragma mark -  
  100. #pragma mark  sendRequestSync  
  101.   
  102. - (void) sendRequestSync  
  103. {  
  104.     [self cleanText];  
  105.       
  106.     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  107.       
  108.     [request setURL:[NSURL URLWithString:@"http://localhost:8888/test.php"]];  
  109.     [request setHTTPMethod:@"GET"];  
  110.       
  111.     NSError *error = nil;  
  112.     NSData *data = [NSURLConnection sendSynchronousRequest:request  
  113.                                          returningResponse:nil  
  114.                                                      error:&error];  
  115.       
  116.     if (data && (!error))  
  117.     {  
  118.         label.text = [[data objectFromJSONData] description];  
  119.     }  
  120. }  
  121.   
  122. #pragma mark -  
  123. #pragma mark  sendRequestAsync  
  124.   
  125. - (void) sendRequestAsync  
  126. {  
  127.     finished = NO;  
  128.       
  129.     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  130.     [request setURL:[NSURL URLWithString:@"http://localhost:8888/test1.php"]];  
  131.     [request setHTTPMethod:@"GET"];  
  132.     [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  133.     [request setTimeoutInterval:5.0f];  
  134.       
  135.     NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request  
  136.                                                                   delegate:self  
  137.                                                           startImmediately:YES];  
  138.       
  139.     [connection start];  
  140.       
  141. //    但是异步模式下带来了一个新的问题,很多情况下,网络请求不在主线程,或者界面等待网络结果,不在主线程的时候,调用线程如果生命周期over,下面这些可能都没有调用到,导致得不到想要得效果,所以需要在NSURLConnection请求后面加点东西来阻塞  
  142.     while(!finished) {  
  143.           
  144.         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];  
  145.           
  146.     }  
  147. }  
  148.   
  149. // 收到回应  
  150. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response  
  151. {  
  152.     // 注意这里将NSURLResponse对象转换成NSHTTPURLResponse对象才能去  
  153.     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;  
  154.       
  155.     if ([response respondsToSelector:@selector(allHeaderFields)])  
  156.     {  
  157.         NSDictionary *dictionary = [httpResponse allHeaderFields];  
  158.         NSLog(@"allHeaderFields: %@",dictionary);  
  159.     }  
  160.     [receivedData setLength:0];  
  161. }  
  162.   
  163. // 接收数据  
  164. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data  
  165. {  
  166.     NSLog(@"get some data");  
  167.     [receivedData appendData:data];  
  168. }  
  169.   
  170. // 数据接收完毕  
  171. - (void)connectionDidFinishLoading:(NSURLConnection *)connection  
  172. {  
  173.     NSString *results = [[NSString alloc] initWithBytes:[receivedData bytes]  
  174.                                                  length:[receivedData length]  
  175.                                                encoding:NSUTF8StringEncoding];  
  176.       
  177.     label.text = [[results objectFromJSONString] description];  
  178.       
  179.     finished = YES;  
  180. }  
  181.   
  182. // 返回错误  
  183. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error  
  184. {  
  185.     NSLog(@"Connection failed: %@", error);  
  186. }  
  187.   
  188. #pragma mark -  
  189. #pragma mark  sendRequestAsyncOther  
  190.   
  191. - (IBAction) sendRequestAsyncOther  
  192. {  
  193.     [self cleanText];  
  194.       
  195.     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  196.     [request setURL:[NSURL URLWithString:@"http://localhost:8888/test2.php"]];  
  197.     [request setHTTPMethod:@"GET"];  
  198.     [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  199.     [request setTimeoutInterval:5.0f];  
  200.       
  201.     [NSURLConnection sendAsynchronousRequest:request  
  202.                                        queue:[NSOperationQueue new]  
  203.                            completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {  
  204.                                  
  205.                                dispatch_async(dispatch_get_main_queue(), ^{  
  206.                                    label.text = [[data objectFromJSONData] description];  
  207.                                });  
  208.                                  
  209.                            }];  
  210. }  
  211.   
  212. @end  

----------------------------------------------

[cpp]  view plain copy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. /** Simple GCD-based timer based on NSTimer. 
  4.  
  5.  Starts immediately and stops when deallocated. This avoids many of the typical problems with NSTimer: 
  6.  
  7.  * RNTimer runs in all modes (unlike NSTimer) 
  8.  * RNTimer runs when there is no runloop (unlike NSTimer) 
  9.  * Repeating RNTimers can easily avoid retain loops (unlike NSTimer) 
  10. */  
  11.   
  12. @interface RNTimer : NSObject  
  13.   
  14. /**--------------------------------------------------------------------------------------- 
  15.  @name Creating a Timer 
  16.  ----------------------------------------------------------------------------------------- 
  17. */  
  18.   
  19. /** Creates and returns a new repeating RNTimer object and starts running it 
  20.  
  21.  After `seconds` seconds have elapsed, the timer fires, executing the block. 
  22.  You will generally need to use a weakSelf pointer to avoid a retain loop. 
  23.  The timer is attached to the main GCD queue. 
  24.  
  25.  @param seconds The number of seconds between firings of the timer. Must be greater than 0. 
  26.  @param block Block to execute. Must be non-nil 
  27.  
  28.  @return A new RNTimer object, configured according to the specified parameters. 
  29. */  
  30. + (RNTimer *)repeatingTimerWithTimeInterval:(NSTimeInterval)seconds block:(dispatch_block_t)block;  
  31.   
  32.   
  33. /**--------------------------------------------------------------------------------------- 
  34.  @name Firing a Timer 
  35.  ----------------------------------------------------------------------------------------- 
  36. */  
  37.   
  38. /** Causes the block to be executed. 
  39.  
  40.  This does not modify the timer. It will still fire on schedule. 
  41. */  
  42. - (void)fire;  
  43.   
  44.   
  45. /**--------------------------------------------------------------------------------------- 
  46.  @name Stopping a Timer 
  47.  ----------------------------------------------------------------------------------------- 
  48. */  
  49.   
  50. /** Stops the receiver from ever firing again 
  51.  
  52.  Once invalidated, a timer cannot be reused. 
  53.  
  54. */  
  55. - (void)invalidate;  
  56. @end  

[cpp]  view plain copy
  1. #import "RNTimer.h"  
  2.   
  3. @interface RNTimer ()  
  4. @property (nonatomic, readwrite, copy) dispatch_block_t block;  
  5. @property (nonatomic, readwrite, assign) dispatch_source_t source;  
  6. @end  
  7.   
  8. @implementation RNTimer  
  9. @synthesize block = _block;  
  10. @synthesize source = _source;  
  11.   
  12. + (RNTimer *)repeatingTimerWithTimeInterval:(NSTimeInterval)seconds  
  13.                                       block:(void (^)(void))block {  
  14.   NSParameterAssert(seconds);  
  15.   NSParameterAssert(block);  
  16.   
  17.   RNTimer *timer = [[self alloc] init];  
  18.   timer.block = block;  
  19.   timer.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,  
  20.                                         0, 0,  
  21.                                         dispatch_get_main_queue());  
  22.       
  23.   uint64_t nsec = (uint64_t)(seconds * NSEC_PER_SEC);  
  24.   dispatch_source_set_timer(timer.source,  
  25.                             dispatch_time(DISPATCH_TIME_NOW, nsec),  
  26.                             nsec, 0);  
  27.   dispatch_source_set_event_handler(timer.source, block);  
  28.   dispatch_resume(timer.source);  
  29.   return timer;  
  30. }  
  31.   
  32. - (void)invalidate {  
  33.   if (self.source) {  
  34.     dispatch_source_cancel(self.source);  
  35.     dispatch_release(self.source);  
  36.     self.source = nil;  
  37.   }  
  38.   self.block = nil;  
  39. }  
  40.   
  41. - (void)dealloc {  
  42.   [self invalidate];  
  43. }  
  44.   
  45. - (void)fire {  
  46.   self.block();  
  47. }  
  48.   
  49.   
  50. @end

















实现代码:

CGDHelper

[cpp]  view plain copy
  1. /* 
  2.  *  Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。 
  3.  *  系统要求:iOS4.0以上。 
  4.  */  
  5.   
  6. #import <Foundation/Foundation.h>  
  7.    
  8. ///////////////////////////////////////     enum 声明     /////////////////////////////////////////////////  
  9.   
  10. //队列优先级  
  11. typedef enum  
  12. {  
  13.     GlobalQueuePriorityDefault = 0,  
  14.     GlobalQueuePriorityHigh = 2,  
  15.     GlobalQueuePriorityLow = -2,  
  16.     GlobalQueuePriorityBackground = INT16_MIN  
  17.       
  18. } GlobalQueuePriority;  
  19.   
  20. //阻塞、非阻塞  
  21. typedef enum  
  22. {  
  23.     PerformBlockFeatureChoke,  
  24.     PerformBlockFeatureUnchoke  
  25.       
  26. } PerformBlockFeature;  
  27.   
  28. //网络请求方法  
  29. typedef enum GCDHelperHttpRequestMethod  
  30. {  
  31.     GCDHelperHttpRequestMethodGET = 0,  
  32.     GCDHelperHttpRequestMethodPOST  
  33.       
  34. } GCDHelperHttpRequestMethod;  
  35.   
  36. ///////////////////////////////////////     Block 声明     /////////////////////////////////////////////////  
  37.   
  38. //返回值void  
  39. typedef     void (^GCDBlock)                         (void);  
  40. typedef     void (^GCDBlock1_Size_t)                 (size_t index);  
  41. typedef     void (^GCDBlock1_Int)                    (int index);  
  42. typedef     void (^GCDBlock1_Bool)                   (BOOL flag);  
  43. typedef     void (^GCDBlock1_Float)                  (float index);  
  44. typedef     void (^GCDBlock1_Obj)                    (id object);  
  45.   
  46. //返回值void,两个形式参数  
  47. typedef     void (^GCDBlock2)                        (id object1, size_t index);  
  48. typedef     void (^GCDBlock2_Obj_Int)                (id object1, int index);  
  49. typedef     void (^GCDBlock2_Obj_Obj)                (id object1, id object2);  
  50.   
  51. //有返回值  
  52. typedef     id   (^GCD_Obj_Block_Obj)                (id object);  
  53. typedef     id   (^GCD_Obj_Block_Void)               (void);  
  54.   
  55. typedef     void (^GCDHttpRequestBlock)              (NSURLResponse *response, NSError *error, NSData *data);  
  56.   
  57.   
  58. ///////////////////////////////////////     GCDHelper 声明     /////////////////////////////////////////////////  
  59.   
  60. @interface GCDHelper : NSObject  
  61.   
  62. /* 获取3种队列 */  
  63. + (dispatch_queue_t) gcdMainQueue;  
  64. + (dispatch_queue_t) gcdGlobalQueue:(GlobalQueuePriority) priority;  
  65. + (dispatch_queue_t) gcdCustomQueue:(NSString *) queueName;  
  66.   
  67. //后台执行  
  68. + (void) gcdPerformBlockAsynchronous:(GCDBlock) block;  
  69.   
  70. //后台获取数据后,回到主线程  
  71. + (void) gcdPerformBlockAsynchronous:(GCDBlock) blockAsyn  
  72.                          finishOnMainQueue:(GCDBlock) blockM;  
  73.   
  74.   
  75. /* 3种队列上执行Block  
  76.  * 
  77.  * 是否阻塞执行:(PerformBlockFeature) feature 
  78.  * 全局队列优先级:(GlobalQueuePriority) priority 
  79.  */  
  80. + (void) gcdPerformBlockOnMainQueue:(GCDBlock) block feature:(PerformBlockFeature) feature;  
  81.   
  82. + (void) gcdPerformBlockOnGlobalQueue:(GCDBlock) block  
  83.                               feature:(PerformBlockFeature) feature  
  84.                              priority:(GlobalQueuePriority) priority;  
  85.   
  86. + (void) gcdPerformBlockOnCustomQueue:(GCDBlock) block  
  87.                               feature:(PerformBlockFeature) feature  
  88.                                  name:(NSString *) queueName;  
  89.   
  90.   
  91. //延迟执行方法  
  92. + (void) gcdPerformBlock:(GCDBlock) block  
  93.                  onQueue:(dispatch_queue_t) queue  
  94.              delaySecond:(int64_t) second;  
  95.   
  96.   
  97. //只执行一次  
  98. + (void) gcdPerformBlockOnce:(GCDBlock) block;  
  99.   
  100. //并发  
  101. + (void) gcdBatchPerformBlocks:(NSArray *) blockArray finally:(GCDBlock) finallyBlock;  
  102.   
  103. + (void) gcdBatchPerformBlockWithData:(NSArray *) dataArray  
  104.           maxConcurrentOperationCount:(uint) count  
  105.                           handleBlock:(GCDBlock1_Obj) block  
  106.                               finally:(GCDBlock1_Obj) finallyBlock;  
  107.   
  108.   
  109.   
  110. @end  
  111.   
  112. ///////////////////////////////////////     图片下载     /////////////////////////////////////////////////  
  113.   
  114. @interface GCDHelper (ImageDownload)  
  115.   
  116. - (void) gcdImageWithURLString:(NSString *) URLString;  
  117. - (void) gcdImageWithURLString:(NSString *) URLString completion:(GCDBlock2_Obj_Obj) completion;  
  118.   
  119. @end  
  120.   
  121. ///////////////////////////////////////     网络请求     /////////////////////////////////////////////////  
  122.   
  123. GCDBlock1_Bool _netWorkBlock;  
  124. @interface GCDHelper (NetworkConnect)  
  125.   
  126. //网络连接判断、实时监控  
  127. - (void) gcdNetWorkGuarder:(NSString *) hostname withBlock:(GCDBlock1_Bool) block;  
  128.   
  129. @end  
  130.   
  131.   
  132. @interface GCDHelper (HttpRequest)  
  133.   
  134. //GCD请求网络(GET方式测试通过,POST方式测试未通过)  
  135. - (void) gcdHttpRequestWithURL:(NSString *) URLString  
  136.                     httpMethod:(GCDHelperHttpRequestMethod) method  
  137.                         params:(NSDictionary *) params  
  138.                        timeout:(NSTimeInterval) time  
  139.                        success:(GCDHttpRequestBlock) successBlock  
  140.                           fail:(GCDHttpRequestBlock) failBlock;  
  141.   
  142. @end  



[cpp]  view plain copy
  1. #import "GCDHelper.h"  
  2.   
  3. #import <SystemConfiguration/SystemConfiguration.h>  
  4.   
  5. #import <sys/socket.h>  
  6. #import <netinet/in.h>  
  7. #import <netinet6/in6.h>  
  8. #import <arpa/inet.h>  
  9. #import <ifaddrs.h>  
  10. #import <netdb.h>  
  11.   
  12. //Error  
  13. #define GCDHelperErrorURLISNULL   [NSError errorWithDomain:@"please setup GCDHelper‘s url or urlString" code:100 userInfo:nil]  
  14. #define GCDHelperErrorRequestISNULL  [NSError errorWithDomain:@"request can not be nil!" code:101 userInfo:nil]  
  15. #define GCDHelperErrorFileExist    [NSError errorWithDomain:@"File Exist!" code:102 userInfo:nil]  
  16. #define GCDHelperErrorCreateFail   [NSError errorWithDomain:@"Create File Fail!" code:103 userInfo:nil]  
  17.   
  18. //下载的临时文件的后缀  
  19. #define kTHDownLoadTask_TempSuffix  @".TempDownload"  
  20. //计算下载速度的取样时间  
  21. #define kTHDownLoadTimerInterval  2.0  
  22. //THDispatchQueue默认的并发数  
  23. #define kTHDispatchQueueDefaultConcurrentCount 10  
  24.   
  25. #define kDefaultTimeoutInterval  15  
  26.   
  27.   
  28. static NSString * const BOUNDRY        = @"--------------------------7d71a819230404";  
  29.   
  30.   
  31. @implementation GCDHelper  
  32.   
  33. - (void) dealloc  
  34. {  
  35.     [super dealloc];  
  36. }  
  37.   
  38. - (id) init  
  39. {  
  40.     if (self = [super init])  
  41.     {  
  42.     }  
  43.       
  44.     return self;  
  45. }  
  46.   
  47. #pragma mark -  
  48. #pragma mark 获取队列  
  49.   
  50. + (dispatch_queue_t) gcdMainQueue  
  51. {  
  52.     return dispatch_get_main_queue();  
  53. }  
  54.   
  55. + (dispatch_queue_t) gcdGlobalQueue:(GlobalQueuePriority) priority  
  56. {  
  57.     switch (priority)  
  58.     {  
  59.         case GlobalQueuePriorityDefault:  
  60.             return dispatch_get_global_queue(priority, 0);  
  61.             break;  
  62.         case GlobalQueuePriorityHigh:  
  63.             return dispatch_get_global_queue(priority, 0);  
  64.             break;  
  65.         case GlobalQueuePriorityLow:  
  66.             return dispatch_get_global_queue(priority, 0);  
  67.             break;  
  68.         case GlobalQueuePriorityBackground:  
  69.             return dispatch_get_global_queue(priority, 0);  
  70.             break;  
  71.               
  72.         default:  
  73.             return dispatch_get_global_queue(GlobalQueuePriorityDefault, 0);  
  74.             break;  
  75.     }  
  76. }  
  77.   
  78. + (dispatch_queue_t) gcdCustomQueue:(NSString *) queueName;  
  79. {  
  80.     return dispatch_queue_create([queueName UTF8String], NULL);  
  81. }  
  82.   
  83. #pragma mark -  
  84. #pragma mark 3种队列上执行Block  
  85.   
  86. + (void) gcdPerformBlockOnMainQueue:(GCDBlock) block feature:(PerformBlockFeature) feature  
  87. {  
  88.     switch (feature)  
  89.     {  
  90.         case PerformBlockFeatureChoke:  
  91.             dispatch_sync([GCDHelper gcdMainQueue], block);  
  92.             break;  
  93.               
  94.         case PerformBlockFeatureUnchoke:  
  95.             dispatch_async([GCDHelper gcdMainQueue], block);  
  96.             break;  
  97.               
  98.         default:  
  99.             dispatch_sync([GCDHelper gcdMainQueue], block);  
  100.             break;  
  101.     }  
  102. }  
  103.   
  104. + (void) gcdPerformBlockOnGlobalQueue:(GCDBlock) block feature:(PerformBlockFeature) feature priority:(GlobalQueuePriority) priority  
  105. {  
  106.     switch (feature)  
  107.     {  
  108.         case PerformBlockFeatureChoke:  
  109.             dispatch_sync([GCDHelper gcdGlobalQueue:priority], block);  
  110.             break;  
  111.               
  112.         case PerformBlockFeatureUnchoke:  
  113.             dispatch_async([GCDHelper gcdGlobalQueue:priority], block);  
  114.             break;  
  115.               
  116.         default:  
  117.             dispatch_sync([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], block);  
  118.             break;  
  119.     }  
  120. }  
  121.   
  122. + (void) gcdPerformBlockOnCustomQueue:(GCDBlock) block feature:(PerformBlockFeature) feature name:(NSString *) queueName  
  123. {  
  124.     switch (feature)  
  125.     {  
  126.         case PerformBlockFeatureChoke:  
  127.             dispatch_sync([GCDHelper gcdCustomQueue:queueName], block);  
  128.             break;  
  129.               
  130.         case PerformBlockFeatureUnchoke:  
  131.             dispatch_async([GCDHelper gcdCustomQueue:queueName], block);  
  132.             break;  
  133.               
  134.         default:  
  135.             dispatch_sync([GCDHelper gcdCustomQueue:@"com.GCDHelper.Queue"], block);  
  136.             break;  
  137.     }  
  138. }  
  139.   
  140. //后台执行  
  141. + (void) gcdPerformBlockAsynchronous:(GCDBlock) block  
  142. {  
  143.     [GCDHelper gcdPerformBlockOnGlobalQueue:block  
  144.                                     feature:PerformBlockFeatureUnchoke  
  145.                                    priority:GlobalQueuePriorityDefault];  
  146. }  
  147.   
  148. //后台获取数据后,回到主线程  
  149. + (void) gcdPerformBlockAsynchronous:(GCDBlock) blockAsyn  
  150.                    finishOnMainQueue:(GCDBlock) blockM  
  151. {  
  152.     dispatch_async([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], ^{  
  153.         blockAsyn();  
  154.         dispatch_async([GCDHelper gcdMainQueue], ^{  
  155.             blockM();  
  156.         });  
  157.     });  
  158. }  
  159.   
  160. #pragma mark -  
  161. #pragma mark 队列延迟时间执行方法  
  162. + (void) gcdPerformBlock:(GCDBlock) block onQueue:(dispatch_queue_t) queue delaySecond:(int64_t) second  
  163. {  
  164.     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, second * NSEC_PER_SEC);  
  165.     dispatch_after(popTime, queue, block);  
  166. }  
  167.   
  168. #pragma mark -  
  169. #pragma mark 只执行一次  
  170.   
  171. + (void) gcdPerformBlockOnce:(GCDBlock) block  
  172. {  
  173.     static dispatch_once_t onceToken;  
  174.     dispatch_once(&onceToken, block);  
  175. }  
  176.   
  177. #pragma mark -  
  178. #pragma mark 无序并发  
  179.   
  180. + (void) gcdBatchPerformBlocks:(NSArray *) blockArray finally:(GCDBlock) finallyBlock  
  181. {  
  182.     [blockArray retain];  
  183.       
  184.     dispatch_queue_t queue = [GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault];  
  185.     dispatch_group_t group = dispatch_group_create();  
  186.       
  187.     for(GCDBlock block in blockArray)  
  188.     {  
  189.         dispatch_group_async(group, queue, ^{  
  190.             block();  
  191.         });  
  192.     }  
  193.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  194.       
  195.     dispatch_async([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], ^{  
  196.         finallyBlock();  
  197.     });  
  198.       
  199.     dispatch_release(group);  
  200.       
  201.     [blockArray release];  
  202. }  
  203.   
  204. + (void) gcdBatchPerformBlockWithData:(NSArray *) dataArray  
  205.           maxConcurrentOperationCount:(uint) count  
  206.                           handleBlock:(GCDBlock1_Obj) block  
  207.                               finally:(GCDBlock1_Obj) finallyBlock  
  208. {  
  209.     [dataArray retain];  
  210.       
  211.     dispatch_queue_t queue = [GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault];  
  212.     dispatch_group_t group = dispatch_group_create();  
  213.     dispatch_semaphore_t semaphore = dispatch_semaphore_create(count);  
  214.     for(id obj in dataArray)  
  215.     {  
  216.         NSLog(@"并发中");  
  217.         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);  
  218.         dispatch_group_async(group, queue, ^{  
  219.             block(obj);  
  220.             dispatch_semaphore_signal(semaphore);  
  221.         });  
  222.     }  
  223.       
  224.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  225.     dispatch_group_notify(group, queue, ^{  
  226.         finallyBlock(dataArray);  
  227.     });  
  228.     dispatch_release(group);  
  229.       
  230.     [dataArray release];  
  231. }  
  232.   
  233.   
  234.   
  235. #pragma mark -  
  236. #pragma mark 图片下载  
  237.   
  238. - (void) gcdImageWithURLString:(NSString *) URLString  
  239. {  
  240.     [self gcdImageWithURLString:URLString completion:nil];  
  241. }  
  242.   
  243. - (void) gcdImageWithURLString:(NSString *) URLString completion:(GCDBlock2_Obj_Obj) completion  
  244. {  
  245.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  246.           
  247.         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  248.         [request setURL:[NSURL URLWithString:URLString]];  
  249.         [request setHTTPMethod:@"GET"];  
  250.         NSData *returnData = [NSURLConnection sendSynchronousRequest:request  
  251.                                                    returningResponse:nil  
  252.                                                                error:nil];  
  253.         [request release];  
  254.           
  255.         UIImage *image  = [UIImage imageWithData:returnData];  
  256.           
  257.         if (image)  
  258.         {  
  259.             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  260.                 completion(image, URLString);  
  261.             });  
  262.         } else  
  263.         {  
  264.             dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  265.                 completion(image, URLString);  
  266.             });  
  267.         }  
  268.     });  
  269. }  
  270.   
  271. @end  
  272.   
  273.   
  274. #pragma mark -  
  275. #pragma mark 网络部分  
  276.   
  277. @implementation GCDHelper (NetworkConnect)  
  278.   
  279. - (BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags  
  280. {  
  281.     BOOL connectionUP = YES;  
  282.       
  283.     if(!(flags & kSCNetworkReachabilityFlagsReachable))  
  284.         connectionUP = NO;  
  285.       
  286.     if( (flags & (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)) == (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) )  
  287.         connectionUP = NO;  
  288.       
  289.     return connectionUP;  
  290. }  
  291.   
  292. -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags  
  293. {  
  294.     dispatch_async(dispatch_get_main_queue(), ^{  
  295.         _netWorkBlock([self isReachableWithFlags:flags]);  
  296.     });  
  297. }  
  298.   
  299. static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)  
  300. {  
  301.     @autoreleasepool  
  302.     {  
  303.         [(GCDHelper *)info reachabilityChanged:flags];  
  304.     }  
  305. }  
  306.   
  307. - (void) gcdNetWorkGuarder:(NSString *) hostname withBlock:(GCDBlock1_Bool) block  
  308. {  
  309.     _netWorkBlock = block;  
  310.       
  311.     SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);  
  312.     SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };  
  313.     dispatch_queue_t queue = dispatch_queue_create("com.myself.reachability", NULL);  
  314.     context.info = (void *)self;  
  315.     SCNetworkReachabilitySetCallback(ref, TMReachabilityCallback, &context);  
  316.     SCNetworkReachabilitySetDispatchQueue(ref, queue);  
  317. }  
  318.   
  319. @end  
  320.   
  321. @implementation GCDHelper(HttpRequest)  
  322.   
  323. - (void) startPOSTHTTPRequest:(NSString *) URLString  
  324.                        params:(NSDictionary *) params  
  325.                       timeout:(NSTimeInterval) time  
  326.                       success:(GCDHttpRequestBlock) successBlock  
  327.                          fail:(GCDHttpRequestBlock) failBlock  
  328. {  
  329.     [params retain];  
  330.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  331.           
  332.         __block NSURLResponse  *response = nil;  
  333.         __block NSError *error = nil;  
  334.         __block NSData *receiveData = nil;  
  335.           
  336.         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  337.           
  338.         [request setURL:[NSURL URLWithString:[URLString lowercaseString]]];  
  339.         [request setHTTPMethod:@"POST"];  
  340.         [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  341.         [request setTimeoutInterval:time];  
  342.           
  343.         if (!request)  
  344.         {  
  345.             NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"发送请求失败", @"errorKey", nil];  
  346.             error = [NSError errorWithDomain:@"www.myself.com" code:100 userInfo:errorInfo];  
  347.               
  348.             dispatch_async(dispatch_get_main_queue(), ^{  
  349.                 successBlock(response, error, receiveData);  
  350.             });  
  351.               
  352.             return;  
  353.         }  
  354.           
  355.         if (params != nil)  
  356.         {  
  357.             [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", BOUNDRY]  
  358.            forHTTPHeaderField:@"Content-Type"];  
  359.               
  360.             int len=512;  
  361.             NSMutableData *postData =[NSMutableData dataWithCapacity:len];  
  362.             [postData appendData:[[NSString stringWithFormat:@"--%@/r/n", BOUNDRY]  
  363.                                   dataUsingEncoding:NSUTF8StringEncoding]];  
  364.             int i=0;  
  365.             int cnt = [params count];  
  366.               
  367.             for (NSString *key in [params allKeys])  
  368.             {  
  369.                 // NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"/r/n/r/n", key];  
  370.                 [postData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"/r/n/r/n", key] dataUsingEncoding:NSUTF8StringEncoding]];  
  371.                   
  372.                 [postData  appendData: [[NSString stringWithFormat:@"%@",[params objectForKey:key]]  
  373.                                         dataUsingEncoding:NSUTF8StringEncoding]];  
  374.                 if(i != cnt - 1)  
  375.                 {  
  376.                     [postData appendData:[[NSString stringWithFormat:@"/r/n--%@/r/n", BOUNDRY]  
  377.                                           dataUsingEncoding:NSUTF8StringEncoding]];  
  378.                 }  
  379.                 i++ ;  
  380.             }  
  381.             [postData  appendData:[[NSString stringWithFormat:@"/r/n--%@--/r/n", BOUNDRY]  
  382.                                    dataUsingEncoding:NSUTF8StringEncoding]];  
  383.               
  384.             [request  setHTTPBody:postData];  
  385.         }  
  386.           
  387.         receiveData = [[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] retain];  
  388.         if (!error)  
  389.         {  
  390.             dispatch_async(dispatch_get_main_queue(), ^{  
  391.                 successBlock(response, nil, receiveData);  
  392.             });  
  393.         }  
  394.         else  
  395.         {  
  396.             dispatch_async(dispatch_get_main_queue(), ^{  
  397.                 successBlock(response, error, receiveData);  
  398.             });  
  399.         }  
  400.           
  401.         [request release];  
  402.     });  
  403.       
  404.     [params release];  
  405. }  
  406.   
  407. - (void) startGETHTTPRequest:(NSString *) URLString  
  408.                       params:(NSDictionary *) params  
  409.                      timeout:(NSTimeInterval) time  
  410.                      success:(GCDHttpRequestBlock) successBlock  
  411.                         fail:(GCDHttpRequestBlock) failBlock  
  412. {  
  413.     [params retain];  
  414.       
  415.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  416.         __block NSURLResponse  *response = nil;  
  417.         __block NSError *error = nil;  
  418.         __block NSData *receiveData = nil;  
  419.           
  420.         NSMutableString *paramsString = [[NSMutableString alloc] init];  
  421.         for(NSString *key in params)  
  422.         {  
  423.             [paramsString appendFormat:@"&%@=%@", key, [params objectForKey:key]];  
  424.         }  
  425.         NSString *requestString = [[NSString alloc] initWithFormat:@"%@%@", URLString, paramsString];  
  426.         NSURL *reqUrl = [[NSURL alloc] initWithString:requestString];  
  427.           
  428.         [paramsString release];  
  429.         [requestString release];  
  430.           
  431.         NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  432.           
  433.         [request setURL:reqUrl];  
  434.         [request setHTTPMethod:@"GET"];  
  435.         [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  436.         [request setTimeoutInterval:time];  
  437.           
  438.         [reqUrl release];  
  439.       
  440.         if (request)  
  441.         {  
  442.             receiveData = [[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] retain];  
  443.         }  
  444.           
  445.         if (!error)  
  446.         {  
  447.             dispatch_async(dispatch_get_main_queue(), ^{  
  448.                 successBlock(response, nil, receiveData);  
  449.             });  
  450.         }  
  451.         else  
  452.         {  
  453.             dispatch_async(dispatch_get_main_queue(), ^{  
  454.                 successBlock(response, error, receiveData);  
  455.             });  
  456.         }  
  457.           
  458.         [request release];  
  459.     });  
  460.       
  461.     [params release];  
  462. }  
  463.   
  464. - (void) gcdHttpRequestWithURL:(NSString *) URLString  
  465.                     httpMethod:(GCDHelperHttpRequestMethod) method  
  466.                         params:(NSDictionary *) params  
  467.                        timeout:(NSTimeInterval) time  
  468.                        success:(GCDHttpRequestBlock) successBlock  
  469.                           fail:(GCDHttpRequestBlock) failBlock  
  470. {  
  471.     switch (method)  
  472.     {  
  473.         case GCDHelperHttpRequestMethodGET:  
  474.         {  
  475.             [self startGETHTTPRequest:URLString params:params timeout:time success:successBlock fail:failBlock];  
  476.             break;  
  477.         }  
  478.         case GCDHelperHttpRequestMethodPOST:  
  479.         {  
  480.             [self startPOSTHTTPRequest:URLString params:params timeout:time success:successBlock fail:failBlock];  
  481.             break;  
  482.         }  
  483.   
  484.         default:  
  485.             break;  
  486.     }  
  487. }  
  488.   
  489. @end  




用法举例:

一、基本概念举例:

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface BaseViewController : UIViewController  
  4. {  
  5.     IBOutlet UITextField *field1;  
  6.     IBOutlet UITextField *field2;  
  7.     IBOutlet UITextField *field3;  
  8.       
  9.     IBOutlet UITextField *textField;  
  10.       
  11.     dispatch_queue_t queue;  
  12. }  
  13.   
  14. - (IBAction) calculate:(id)sender;  
  15. - (IBAction) operationQueue:(id)sender;  
  16. - (IBAction) gcd:(id)sender;  
  17.   
  18. - (IBAction) notchoke:(id)sender;  
  19. - (IBAction) choke:(id)sender;  
  20.   
  21. - (IBAction) getUIData:(id)sender;  
  22.   
  23.   
  24. - (IBAction)startQueue:(id)sender;  
  25. - (IBAction)suspendQueue:(id)sender;  
  26. - (IBAction)resumeQueue:(id)sender;  
  27.   
  28. @end  

[cpp]  view plain copy
  1. #import "BaseViewController.h"  
  2.   
  3. @implementation BaseViewController  
  4.   
  5. - (void) dealloc  
  6. {  
  7.     dispatch_release(queue);  
  8.       
  9.     [super dealloc];  
  10. }  
  11.   
  12. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  13. {  
  14.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  15.     if (self) {  
  16.         queue = dispatch_queue_create("sss", NULL);  
  17.     }  
  18.     return self;  
  19. }  
  20.   
  21. - (void)viewDidLoad  
  22. {  
  23.     [super viewDidLoad];  
  24.     // Do any additional setup after loading the view from its nib.  
  25. }  
  26.   
  27. - (void) longTask:(id) sender  
  28. {  
  29.     NSMutableArray *arr = [NSMutableArray array];  
  30.     for (int i = 0; i < 1000; i++) {  
  31.           
  32.         [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  33.         NSLog(@"longTask:%d", i);  
  34.     }  
  35. }  
  36.   
  37. - (void) longTaskOther:(id) sender  
  38. {  
  39.     NSMutableArray *arr = [NSMutableArray array];  
  40.     for (int i = 0; i < 10000; i++) {  
  41.           
  42.         [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  43.         NSLog(@"longTaskOther:%d", i);  
  44.     }  
  45. }  
  46.   
  47. - (IBAction) calculate:(id)sender  
  48. {  
  49.     field3.text = [NSString stringWithFormat:@"%f", [field1.text floatValue] - [field2.text floatValue]];  
  50. }  
  51. - (IBAction) operationQueue:(id)sender;  
  52. {  
  53.     NSOperationQueue *aqueue = [NSOperationQueue new];  
  54.     NSInvocationOperation *operation = [[NSInvocationOperation alloc]  
  55.                                         initWithTarget:self  
  56.                                         selector:@selector(longTask:)  
  57.                                         object:nil];  
  58.     NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]  
  59.                                         initWithTarget:self  
  60.                                         selector:@selector(longTaskOther:)  
  61.                                         object:nil];  
  62.       
  63.   
  64.     [aqueue addOperation:operation];  
  65.     [aqueue addOperation:operation1];  
  66.       
  67.     [operation release];  
  68.     [operation1 release];  
  69. }  
  70. - (IBAction) gcd:(id)sender  //3.192999  
  71. {  
  72.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  73.         NSMutableArray *arr = [NSMutableArray array];  
  74.         for (int i = 0; i < 1000; i++) {  
  75.               
  76.             [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  77.             NSLog(@"longTask:%d", i);  
  78.         }  
  79.     }];  
  80.       
  81.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  82.         NSMutableArray *arr = [NSMutableArray array];  
  83.         for (int i = 0; i < 10000; i++) {  
  84.               
  85.             [arr addObject:[NSMutableArray arrayWithObject:@(i)]];  
  86.             NSLog(@"longTaskOther:%d", i);  
  87.         }  
  88.     }];  
  89. }  
  90.   
  91. //////////////////////////////////////////////////////  
  92.   
  93. - (IBAction)notchoke:(id)sender  
  94. {  
  95.     dispatch_async(dispatch_get_main_queue(), ^{  
  96.         NSLog(@"qqq");  
  97.     });  
  98.   
  99.     NSLog(@"不阻塞");  
  100. }  
  101.   
  102.   
  103. //Calls to dispatch_sync() targeting the current queue will result  
  104. //* in dead-lock. Use of dispatch_sync() is also subject to the same  
  105. //* multi-party dead-lock problems that may result from the use of a mutex.  
  106. //* Use of dispatch_async() is preferred.  
  107. //在当前队列上调用dispatch_sync() 会导致死锁。调用dispatch_sync(),并使用mutex 经常会导致多方死锁问题。  
  108. - (IBAction) choke:(id)sender  
  109. {  
  110.     dispatch_queue_t exampleQueue;  
  111.       
  112.     int i = 3;  
  113.     switch (i) {  
  114.         case 0:  
  115.             exampleQueue = dispatch_get_global_queue(0, 0);  
  116.             break;  
  117.         case 1:  
  118.             exampleQueue = dispatch_queue_create("com.abc.xxx", NULL);  
  119.             break;  
  120.         case 2:  
  121.             exampleQueue = dispatch_get_current_queue();  
  122.             break;  
  123.         case 3:  
  124.             exampleQueue = dispatch_get_main_queue();  
  125.             break;  
  126.               
  127.         default:  
  128.             exampleQueue = dispatch_get_global_queue(0, 0);  
  129.             break;  
  130.     }  
  131.       
  132.     dispatch_sync( exampleQueue,^{  
  133.         [self longTask:nil];  
  134.     });  
  135.       
  136.     NSLog(@"task finish");  
  137. }  
  138.   
  139. - (IBAction) getUIData:(id)sender  
  140. {  
  141.     dispatch_async(dispatch_get_global_queue(0, 0), ^{  
  142.           
  143.         __block NSString *stringValue;  
  144.         dispatch_sync(dispatch_get_main_queue(), ^{  
  145.             stringValue = [textField.text copy];  
  146.         });  
  147.           
  148.         [stringValue retain];  
  149.           
  150.         NSLog(@"stringValue:%@", stringValue);  
  151.     });  
  152. }  
  153.   
  154.   
  155.   
  156. //一个要注意的地方是,dispatch queue的挂起是block粒度的。换句话说,挂起一个queue并不会将当前正在执行的block挂起。它会允许当前执行的block执行完毕,然后后续的block不再会被执行,直至queue被恢复。  
  157. //还有一个注意点:从man页上得来的:如果你挂起了一个queue或者source,那么销毁它之前,必须先对其进行恢复。  
  158. - (IBAction)startQueue:(id)sender  
  159. {  
  160.     dispatch_async(queue, ^{  
  161.         for (int i = 0; i < 10000; i++) {  
  162.             NSLog(@"taskA");  
  163.         }  
  164.     });  
  165.       
  166.     dispatch_async(queue, ^{  
  167.         for (int i = 0; i < 10000; i++) {  
  168.             NSLog(@"taskB");  
  169.         }  
  170.     });  
  171.       
  172.     dispatch_async(queue, ^{  
  173.         for (int i = 0; i < 10000; i++) {  
  174.             NSLog(@"taskC");  
  175.         }  
  176.     });  
  177. }  
  178. - (IBAction)suspendQueue:(id)sender  
  179. {  
  180.     NSLog(@"Queue suspend");  
  181.     dispatch_suspend(queue);  
  182.   
  183. }  
  184. - (IBAction)resumeQueue:(id)sender  
  185. {  
  186.     NSLog(@"Queue resume");  
  187.     dispatch_resume(queue);  
  188.   
  189. }  

二、基本用法举例

例子1:

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface OneViewController : UIViewController  
  4.   
  5.   
  6. //无序并发  
  7. - (IBAction)selector0:(id)sender;  
  8.   
  9. //无序并发处理数据  
  10. - (IBAction)selector100:(id)sender;  
  11.   
  12. //执行一次  
  13. - (IBAction)selector1:(id)sender;  
  14.   
  15. //异步/后台执行  
  16. - (IBAction)selector2:(id)sender;  
  17.   
  18. //后台执行,然后返回主线程  
  19. - (IBAction)selector3:(id)sender;  
  20.   
  21. //三种队列执行  
  22. - (IBAction)selector4:(UISegmentedControl *)sender;  
  23.   
  24. //延迟执行  
  25. - (IBAction)selector5:(id)sender;  
  26.   
  27. @end  

[cpp]  view plain copy
  1. #import "OneViewController.h"  
  2.   
  3. @interface OneViewController ()  
  4.   
  5. @end  
  6.   
  7. @implementation OneViewController  
  8.   
  9. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  10. {  
  11.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  12.     if (self) {  
  13.         // Custom initialization  
  14.     }  
  15.     return self;  
  16. }  
  17.   
  18. - (void)viewDidLoad  
  19. {  
  20.     [super viewDidLoad];  
  21. }  
  22.   
  23. - (NSMutableArray *) getBlockArray  
  24. {  
  25.     NSMutableArray *arr = [[NSMutableArray array] retain];  
  26.       
  27.     GCDBlock b0 = ^{ NSLog(@"无序并发: 0"); sleep(3); }; [arr addObject:b0];  
  28.     GCDBlock b1 = ^{ NSLog(@"无序并发: 1"); }; [arr addObject:b1];  
  29.     GCDBlock b2 = ^{ NSLog(@"无序并发: 2"); }; [arr addObject:b2];  
  30.     GCDBlock b3 = ^{ NSLog(@"无序并发: 3"); }; [arr addObject:b3];  
  31.     GCDBlock b4 = ^{ NSLog(@"无序并发: 4"); }; [arr addObject:b4];  
  32.     GCDBlock b5 = ^{ NSLog(@"无序并发: 5"); }; [arr addObject:b5];  
  33.     GCDBlock b6 = ^{ NSLog(@"无序并发: 6"); }; [arr addObject:b6];  
  34.     GCDBlock b7 = ^{ NSLog(@"无序并发: 7"); }; [arr addObject:b7];  
  35.     GCDBlock b8 = ^{ NSLog(@"无序并发: 8"); }; [arr addObject:b8];  
  36.     GCDBlock b9 = ^{ NSLog(@"无序并发: 9"); }; [arr addObject:b9];  
  37.     GCDBlock b10 = ^{ NSLog(@"无序并发: 10"); }; [arr addObject:b10];  
  38.     GCDBlock b11 = ^{ NSLog(@"无序并发: 11"); }; [arr addObject:b11];  
  39.     GCDBlock b12 = ^{ NSLog(@"无序并发: 12"); }; [arr addObject:b12];  
  40.     GCDBlock b13 = ^{ NSLog(@"无序并发: 13"); }; [arr addObject:b13];  
  41.     GCDBlock b14 = ^{ NSLog(@"无序并发: 14"); }; [arr addObject:b14];  
  42.     GCDBlock b15 = ^{ NSLog(@"无序并发: 15"); }; [arr addObject:b15];  
  43.       
  44.     return arr;  
  45. }  
  46.   
  47. //无序并发  
  48. - (IBAction)selector0:(id)sender  
  49. {  
  50.     [GCDHelper gcdBatchPerformBlocks:[self getBlockArray] finally:^{  
  51.         NSLog(@"一组有序并发完成");  
  52.     }];  
  53.       
  54. //    NSLog(@"一组无序并发完成");  
  55. }  
  56.   
  57.   
  58. - (IBAction)selector100:(id)sender  
  59. {  
  60.     NSMutableArray *arr = [NSMutableArray array];  
  61.     for (int i = 0; i < 100; i++) {  
  62.         [arr addObject:[NSMutableArray array]];  
  63.     }  
  64.       
  65.     __block int i = 0;  
  66.     [GCDHelper gcdBatchPerformBlockWithData:arr maxConcurrentOperationCount:10 handleBlock:^(id object) {  
  67.           
  68.         sleep(1);  
  69.         NSMutableArray *arr = (NSMutableArray *)object;  
  70.         [arr addObject:@(i)];  
  71.         i++;  
  72.     } finally:^(id object) {  
  73.         NSLog(@"arr:%@", object);  
  74.     }];  
  75. }  
  76.   
  77. - (IBAction)selector1:(id)sender  
  78. {  
  79.     [GCDHelper gcdPerformBlockOnce:^{  
  80.         NSLog(@"别想让我执行第二次");  
  81.     }];  
  82.     NSLog(@"不执行~");  
  83. }  
  84.   
  85. //异步/后台执行  
  86. - (IBAction)selector2:(id)sender  
  87. {  
  88.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  89.         sleep(3);  
  90.          NSLog(@"全局队列执行完成");  
  91.     }];  
  92.     NSLog(@"全局队列执行,不影响主队列");  
  93. }  
  94.   
  95. //后台执行,然后返回主线程  
  96. - (IBAction)selector3:(id)sender  
  97. {  
  98.     [GCDHelper gcdPerformBlockAsynchronous:^{  
  99.          
  100.         for (int i = 0; i< 10; i++)  
  101.         {  
  102.             NSLog(@"全局队列执行: %d", i);  
  103.         }  
  104.           
  105.     } finishOnMainQueue:^{  
  106.         NSLog(@"回到主队列");  
  107.     }];  
  108. }  
  109.   
  110. //三种队列执行  
  111. - (IBAction)selector4:(UISegmentedControl *)sender  
  112. {  
  113.     switch (sender.selectedSegmentIndex) {  
  114.         case 0:  
  115.         {  
  116.             [GCDHelper gcdPerformBlockOnMainQueue:^{  
  117.                 NSLog(@"主队列执行");  
  118.             } feature:PerformBlockFeatureUnchoke];  
  119.             break;  
  120.         }  
  121.         case 1:  
  122.         {  
  123.             [GCDHelper gcdPerformBlockOnGlobalQueue:^{  
  124.                 NSLog(@"全局队列执行");  
  125.             } feature:PerformBlockFeatureUnchoke priority:GlobalQueuePriorityDefault];  
  126.             break;  
  127.         }  
  128.         case 2:  
  129.         {  
  130.             [GCDHelper gcdPerformBlockOnCustomQueue:^{  
  131.                 NSLog(@"自创建队列执行");  
  132.             } feature:PerformBlockFeatureUnchoke name:@"com.abc.bcd"];  
  133.             break;  
  134.         }  
  135.               
  136.         default:  
  137.             break;  
  138.     }  
  139. }  
  140.   
  141. //延迟执行  
  142. - (IBAction)selector5:(id)sender  
  143. {  
  144.     NSLog(@"延迟 2s 执行");  
  145.     [GCDHelper gcdPerformBlock:^{  
  146.         NSLog(@"执行完毕");  
  147.     } onQueue:[GCDHelper gcdMainQueue] delaySecond:2];  
  148. }  
  149.   
  150. @end  

例子2:

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface MulthreadConcurrentVC : UIViewController  
  4.   
  5.   
  6. @end  

[cpp]  view plain copy
  1. #import "MulthreadConcurrentVC.h"  
  2.   
  3. /* 
  4.   
  5.  如何在GCD中快速的控制并发呢?答案就是 
  6.  dispatch_semaphore,对经常做unix开发的人来讲,我所介绍的内容可能就显得非常入门级了,信号量在他们的多线程开发中再平常不过了。 
  7.  在GCD中有三个函数是semaphore的操作,分别是: 
  8.  dispatch_semaphore_create          创建一个semaphore 
  9.  dispatch_semaphore_signal          发送一个信号 
  10.  dispatch_semaphore_wait              等待信号 
  11.  简单的介绍一下这三个函数,第一个函数有一个整形的参数,我们可以理解为信号的总量,dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量减少1,根据这样的原理,我们便可以快速的创建一个并发控制。 
  12.   
  13.  */  
  14.   
  15.   
  16. /* 
  17.   
  18. 简单的介绍一下这一段代码,创建了一个初使值为10的semaphore,每一次for循环都会创建一个新的线程,线程结束的时候会发送一个信号,线程创建之前会信号等待,所以当同时创建了10个线程之后,for循环就会阻塞,等待有线程结束之后会增加一个信号才继续执行,如此就形成了对并发的控制,如上就是一个并发数为10的一个线程队列。 
  19.   
  20. */  
  21.   
  22. @implementation MulthreadConcurrentVC  
  23.   
  24. - (void) loadView  
  25. {  
  26.     [super loadView];  
  27. }  
  28.   
  29. - (void)aSelector:(id)sender  
  30. {  
  31.     dispatch_group_t group = dispatch_group_create();  
  32.     dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);  
  33.     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  34.     for (int i = 0; i < 100; i++)  
  35.     {  
  36.         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);  
  37.         dispatch_group_async(group, queue, ^{  
  38.             NSLog(@"%i",i);  
  39.             sleep(2);  
  40.             dispatch_semaphore_signal(semaphore);  
  41.         });  
  42.     }  
  43.     dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  44.     dispatch_release(group);  
  45.     dispatch_release(semaphore);  
  46. }  
  47.   
  48. - (void)viewDidLoad  
  49. {  
  50.     [super viewDidLoad];  
  51.       
  52.     UIButton *bt = [UIButton buttonWithType:UIButtonTypeRoundedRect];  
  53.     bt.frame = CGRectMake(100, 100, 120, 120);  
  54.     [bt addTarget:self action:@selector(aSelector:) forControlEvents:UIControlEventTouchUpInside];  
  55.     [self.view addSubview:bt];  
  56. }  

三、GCD实际应用举例

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. #import "GCDHelper.h"  
  4.   
  5. @interface TableViewController : UITableViewController  
  6.   
  7. @end  

[cpp]  view plain copy
  1. #import "TableViewController.h"  
  2. #import "CustomCell.h"  
  3. #import <objc/runtime.h>  
  4.   
  5. static char * const kIndexPathAssociationKey = "JK_indexPath";  
  6.   
  7. @interface TableViewController ()  
  8.   
  9. @end  
  10.   
  11. @implementation TableViewController  
  12.   
  13. - (id)initWithStyle:(UITableViewStyle)style  
  14. {  
  15.     self = [super initWithStyle:style];  
  16.     if (self) {  
  17.         // Custom initialization  
  18.     }  
  19.     return self;  
  20. }  
  21.   
  22. - (void)viewDidLoad  
  23. {  
  24.     [super viewDidLoad];  
  25.   
  26.     self.clearsSelectionOnViewWillAppear = NO;  
  27.     self.navigationItem.rightBarButtonItem = self.editButtonItem;  
  28. }  
  29.   
  30. - (void)didReceiveMemoryWarning  
  31. {  
  32.     [super didReceiveMemoryWarning];  
  33.     // Dispose of any resources that can be recreated.  
  34. }  
  35.   
  36. #pragma mark - Table view data source  
  37.   
  38. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView  
  39. {  
  40.     return 1;  
  41. }  
  42.   
  43. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section  
  44. {  
  45.     return 100;  
  46. }  
  47.   
  48. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  
  49. {  
  50.     static NSString *CellIdentifier = @"Cell";  
  51.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];  
  52.       
  53.     if (cell == nil) {  
  54.         cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];  
  55.         UIImageView *im = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];  
  56.         im.tag = 10;  
  57.         [cell addSubview:im];  
  58.         [im release];  
  59.     }  
  60.       
  61.     return cell;  
  62. }  
  63.   
  64. - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath  
  65. {  
  66. //    http://localhost:8888/Imgs/img0.png  
  67. //    http://theme.blogcn.com/wp-content/themes/coffee-desk/images/rsscoffee.PNG  
  68.       
  69.     NSString *imgURLStr = nil;  
  70.     if ((indexPath.row % 2) == 0)  
  71.     {  
  72.         imgURLStr = @"http://localhost:8888/Imgs/img0.png";  
  73.     } else  
  74.     {  
  75.         imgURLStr = @"http://localhost:8888/Imgs/img1.png";  
  76.     }  
  77.       
  78.     GCDHelper *hp = [GCDHelper new];  
  79.     [hp gcdImageWithURLString:imgURLStr  
  80.                    completion:^(id object1, id object2) {  
  81.                       
  82.                        dispatch_async(dispatch_get_main_queue(), ^{  
  83.                            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];  
  84.                            [(UIImageView *)[cell viewWithTag:10] setImage:(UIImage *)object1];  
  85.                        });  
  86.                    }];  
  87. }  
  88.   
  89. #pragma mark - Table view delegate  
  90.   
  91. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  92. {  
  93. }  
  94.   
  95. #pragma mark -  
  96. #pragma mark - cell重用  
  97.   
  98. - (void)tableViewCellIsPreparingForReuse:(NSNotification *)notification  
  99. {  
  100.     if ([[notification object] isKindOfClass:[CustomCell class]]) {  
  101.         CustomCell *cell = (CustomCell *)[notification object];  
  102.           
  103.         objc_setAssociatedObject(cell,  
  104.                                  kIndexPathAssociationKey,  
  105.                                  nil,  
  106.                                  OBJC_ASSOCIATION_RETAIN);  
  107.           
  108.         [[cell imageView] setImage:nil];  
  109.     }  
  110. }  
  111.   
  112. @end  

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. extern NSString * const kJKPrepareForReuseNotification;  
  4.   
  5. @interface CustomCell : UITableViewCell  
  6.   
  7. @end  

[cpp]  view plain copy
  1. #import "CustomCell.h"  
  2.   
  3. NSString * const kJKPrepareForReuseNotification = @"JKCallbacksTableViewCell_PrepareForReuse";  
  4.   
  5. @implementation CustomCell  
  6.   
  7. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier  
  8. {  
  9.     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];  
  10.     if (self) {  
  11.         //如果cell 的图片发生改变,当cell重用的时候,刷新图片  
  12.           
  13.         [[self imageView] addObserver:self  
  14.                            forKeyPath:@"image"  
  15.                               options:NSKeyValueObservingOptionOld  
  16.                               context:NULL];  
  17.     }  
  18.     return self;  
  19. }  
  20.   
  21. - (void)observeValueForKeyPath:(NSString *)keyPath  
  22.                       ofObject:(id)object  
  23.                         change:(NSDictionary *)change  
  24.                        context:(void *)context  
  25. {  
  26.     NSLog(@"observeValueForKeyPath");  
  27.       
  28.     if (object == [self imageView] &&  
  29.         [keyPath isEqualToString:@"image"] &&  
  30.         ([change objectForKey:NSKeyValueChangeOldKey] == nil ||  
  31.          [change objectForKey:NSKeyValueChangeOldKey] == [NSNull null]))  
  32.     {  
  33.         [self setNeedsLayout];  
  34.     }  
  35. }  
  36.   
  37. - (void)prepareForReuse  
  38. {  
  39.     [[NSNotificationCenter defaultCenter] postNotificationName:kJKPrepareForReuseNotification  
  40.                                                         object:self];  
  41.       
  42.     [super prepareForReuse];  
  43. }  
  44.   
  45. @end  

----------------------------------------------

[cpp]  view plain copy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface NetGuarder : NSObject  
  4.   
  5. + (NetGuarder *) shareNetGuarder;  
  6.   
  7. @end  

[cpp]  view plain copy
  1. #import "NetGuarder.h"  
  2.   
  3. @implementation NetGuarder  
  4.   
  5. static NetGuarder *guarder = nil;  
  6.   
  7. + (void) getNetConnectMsg  
  8. {  
  9.     GCDHelper *hp = [GCDHelper new];  
  10.     [hp gcdNetWorkGuarder:@"www.baidu.com" withBlock:^(BOOL flag) {  
  11.         if (flag)  
  12.         {  
  13.             NSLog(@"Net connect");  
  14.         } else  
  15.         {  
  16.             NSLog(@"Net not connect");  
  17.         }  
  18.     }];  
  19. }  
  20.   
  21. + (NetGuarder *) shareNetGuarder  
  22. {  
  23.     static dispatch_once_t predicate;  
  24.     dispatch_once(&predicate, ^{  
  25.           
  26.         NSLog(@"单例创建");  
  27.         guarder = [[self alloc] init];  
  28.           
  29.         [NetGuarder getNetConnectMsg];  
  30.     });  
  31.       
  32.     return guarder;  
  33. }  
  34.   
  35. @end  

-------------------------------------------

[cpp]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. @interface URLConViewController : UIViewController <NSURLConnectionDataDelegate>  
  4. {  
  5.     IBOutlet UISegmentedControl *segment;  
  6.     IBOutlet UILabel *label;  
  7. }  
  8.   
  9. @end  

[cpp]  view plain copy
  1. #import "URLConViewController.h"  
  2.   
  3. typedef struct _INT  
  4. {  
  5.     int t1;  
  6.       
  7. }INT_STRUCT;  
  8.   
  9. @interface URLConViewController ()  
  10. {  
  11.     NSMutableData *receivedData;  
  12.     BOOL finished;  
  13. }  
  14.   
  15. @end  
  16.   
  17. @implementation URLConViewController  
  18.   
  19. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  20. {  
  21.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  22.     if (self)  
  23.     {  
  24.         receivedData = [[NSMutableData data] retain];  
  25.     }  
  26.     return self;  
  27. }  
  28.   
  29. - (void)viewDidLoad  
  30. {  
  31.     [super viewDidLoad];  
  32. }  
  33.   
  34. - (void)didReceiveMemoryWarning  
  35. {  
  36.     [super didReceiveMemoryWarning];  
  37. }  
  38.   
  39. - (void) cleanText  
  40. {  
  41.     label.text = @"";  
  42. }  
  43.   
  44. - (IBAction)segmentAction:(UISegmentedControl *)sender  
  45. {  
  46.     switch (sender.selectedSegmentIndex) {  
  47.         case 0:  
  48.         {  
  49.             [self sendRequestSync];  
  50.             break;  
  51.         }  
  52.         case 1:  
  53.         {  
  54.             [self sendRequestAsync];  
  55.             break;  
  56.         }  
  57.         case 2:  
  58.         {  
  59.             [self sendRequestAsyncOther];  
  60.             break;  
  61.         }  
  62.         case 3:  
  63.         {  
  64.             [self gcdRequest];  
  65.             break;  
  66.         }  
  67.               
  68.         default:  
  69.             break;  
  70.     }  
  71. }  
  72.   
  73. #pragma mark -  
  74. #pragma mark  GCDRequest  
  75.   
  76. - (void) gcdRequest  
  77. {  
  78.     GCDHelper *hp = [GCDHelper new];  
  79.       
  80.     [hp gcdHttpRequestWithURL:@"http://localhost:8888/test.php"  
  81.                    httpMethod:GCDHelperHttpRequestMethodGET  
  82.                        params:[NSDictionary dictionary]  
  83.                       timeout:5.0f  
  84.                       success:^(NSURLResponse *response, NSError *error, NSData *data) {  
  85.                           if (data && (!error))  
  86.                           {  
  87.                               label.text = [[data objectFromJSONData] description];  
  88.                           }  
  89.                             
  90.                       }  
  91.                          fail:^(NSURLResponse *response, NSError *error, NSData *data) {  
  92.                              if (error)  
  93.                              {  
  94.                                  label.text = [error description];  
  95.                              }  
  96.                          }];  
  97. }  
  98.   
  99. #pragma mark -  
  100. #pragma mark  sendRequestSync  
  101.   
  102. - (void) sendRequestSync  
  103. {  
  104.     [self cleanText];  
  105.       
  106.     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  107.       
  108.     [request setURL:[NSURL URLWithString:@"http://localhost:8888/test.php"]];  
  109.     [request setHTTPMethod:@"GET"];  
  110.       
  111.     NSError *error = nil;  
  112.     NSData *data = [NSURLConnection sendSynchronousRequest:request  
  113.                                          returningResponse:nil  
  114.                                                      error:&error];  
  115.       
  116.     if (data && (!error))  
  117.     {  
  118.         label.text = [[data objectFromJSONData] description];  
  119.     }  
  120. }  
  121.   
  122. #pragma mark -  
  123. #pragma mark  sendRequestAsync  
  124.   
  125. - (void) sendRequestAsync  
  126. {  
  127.     finished = NO;  
  128.       
  129.     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  130.     [request setURL:[NSURL URLWithString:@"http://localhost:8888/test1.php"]];  
  131.     [request setHTTPMethod:@"GET"];  
  132.     [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  133.     [request setTimeoutInterval:5.0f];  
  134.       
  135.     NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request  
  136.                                                                   delegate:self  
  137.                                                           startImmediately:YES];  
  138.       
  139.     [connection start];  
  140.       
  141. //    但是异步模式下带来了一个新的问题,很多情况下,网络请求不在主线程,或者界面等待网络结果,不在主线程的时候,调用线程如果生命周期over,下面这些可能都没有调用到,导致得不到想要得效果,所以需要在NSURLConnection请求后面加点东西来阻塞  
  142.     while(!finished) {  
  143.           
  144.         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];  
  145.           
  146.     }  
  147. }  
  148.   
  149. // 收到回应  
  150. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response  
  151. {  
  152.     // 注意这里将NSURLResponse对象转换成NSHTTPURLResponse对象才能去  
  153.     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;  
  154.       
  155.     if ([response respondsToSelector:@selector(allHeaderFields)])  
  156.     {  
  157.         NSDictionary *dictionary = [httpResponse allHeaderFields];  
  158.         NSLog(@"allHeaderFields: %@",dictionary);  
  159.     }  
  160.     [receivedData setLength:0];  
  161. }  
  162.   
  163. // 接收数据  
  164. - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data  
  165. {  
  166.     NSLog(@"get some data");  
  167.     [receivedData appendData:data];  
  168. }  
  169.   
  170. // 数据接收完毕  
  171. - (void)connectionDidFinishLoading:(NSURLConnection *)connection  
  172. {  
  173.     NSString *results = [[NSString alloc] initWithBytes:[receivedData bytes]  
  174.                                                  length:[receivedData length]  
  175.                                                encoding:NSUTF8StringEncoding];  
  176.       
  177.     label.text = [[results objectFromJSONString] description];  
  178.       
  179.     finished = YES;  
  180. }  
  181.   
  182. // 返回错误  
  183. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error  
  184. {  
  185.     NSLog(@"Connection failed: %@", error);  
  186. }  
  187.   
  188. #pragma mark -  
  189. #pragma mark  sendRequestAsyncOther  
  190.   
  191. - (IBAction) sendRequestAsyncOther  
  192. {  
  193.     [self cleanText];  
  194.       
  195.     NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];  
  196.     [request setURL:[NSURL URLWithString:@"http://localhost:8888/test2.php"]];  
  197.     [request setHTTPMethod:@"GET"];  
  198.     [request setCachePolicy:NSURLRequestUseProtocolCachePolicy];  
  199.     [request setTimeoutInterval:5.0f];  
  200.       
  201.     [NSURLConnection sendAsynchronousRequest:request  
  202.                                        queue:[NSOperationQueue new]  
  203.                            completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {  
  204.                                  
  205.                                dispatch_async(dispatch_get_main_queue(), ^{  
  206.                                    label.text = [[data objectFromJSONData] description];  
  207.                                });  
  208.                                  
  209.                            }];  
  210. }  
  211.   
  212. @end  

----------------------------------------------

[cpp]  view plain copy
  1. #import <Foundation/Foundation.h>  
  2.   
  3. /** Simple GCD-based timer based on NSTimer. 
  4.  
  5.  Starts immediately and stops when deallocated. This avoids many of the typical problems with NSTimer: 
  6.  
  7.  * RNTimer runs in all modes (unlike NSTimer) 
  8.  * RNTimer runs when there is no runloop (unlike NSTimer) 
  9.  * Repeating RNTimers can easily avoid retain loops (unlike NSTimer) 
  10. */  
  11.   
  12. @interface RNTimer : NSObject  
  13.   
  14. /**--------------------------------------------------------------------------------------- 
  15.  @name Creating a Timer 
  16.  ----------------------------------------------------------------------------------------- 
  17. */  
  18.   
  19. /** Creates and returns a new repeating RNTimer object and starts running it 
  20.  
  21.  After `seconds` seconds have elapsed, the timer fires, executing the block. 
  22.  You will generally need to use a weakSelf pointer to avoid a retain loop. 
  23.  The timer is attached to the main GCD queue. 
  24.  
  25.  @param seconds The number of seconds between firings of the timer. Must be greater than 0. 
  26.  @param block Block to execute. Must be non-nil 
  27.  
  28.  @return A new RNTimer object, configured according to the specified parameters. 
  29. */  
  30. + (RNTimer *)repeatingTimerWithTimeInterval:(NSTimeInterval)seconds block:(dispatch_block_t)block;  
  31.   
  32.   
  33. /**--------------------------------------------------------------------------------------- 
  34.  @name Firing a Timer 
  35.  ----------------------------------------------------------------------------------------- 
  36. */  
  37.   
  38. /** Causes the block to be executed. 
  39.  
  40.  This does not modify the timer. It will still fire on schedule. 
  41. */  
  42. - (void)fire;  
  43.   
  44.   
  45. /**--------------------------------------------------------------------------------------- 
  46.  @name Stopping a Timer 
  47.  ----------------------------------------------------------------------------------------- 
  48. */  
  49.   
  50. /** Stops the receiver from ever firing again 
  51.  
  52.  Once invalidated, a timer cannot be reused. 
  53.  
  54. */  
  55. - (void)invalidate;  
  56. @end  

[cpp]  view plain copy
  1. #import "RNTimer.h"  
  2.   
  3. @interface RNTimer ()  
  4. @property (nonatomic, readwrite, copy) dispatch_block_t block;  
  5. @property (nonatomic, readwrite, assign) dispatch_source_t source;  
  6. @end  
  7.   
  8. @implementation RNTimer  
  9. @synthesize block = _block;  
  10. @synthesize source = _source;  
  11.   
  12. + (RNTimer *)repeatingTimerWithTimeInterval:(NSTimeInterval)seconds  
  13.                                       block:(void (^)(void))block {  
  14.   NSParameterAssert(seconds);  
  15.   NSParameterAssert(block);  
  16.   
  17.   RNTimer *timer = [[self alloc] init];  
  18.   timer.block = block;  
  19.   timer.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,  
  20.                                         0, 0,  
  21.                                         dispatch_get_main_queue());  
  22.       
  23.   uint64_t nsec = (uint64_t)(seconds * NSEC_PER_SEC);  
  24.   dispatch_source_set_timer(timer.source,  
  25.                             dispatch_time(DISPATCH_TIME_NOW, nsec),  
  26.                             nsec, 0);  
  27.   dispatch_source_set_event_handler(timer.source, block);  
  28.   dispatch_resume(timer.source);  
  29.   return timer;  
  30. }  
  31.   
  32. - (void)invalidate {  
  33.   if (self.source) {  
  34.     dispatch_source_cancel(self.source);  
  35.     dispatch_release(self.source);  
  36.     self.source = nil;  
  37.   }  
  38.   self.block = nil;  
  39. }  
  40.   
  41. - (void)dealloc {  
  42.   [self invalidate];  
  43. }  
  44.   
  45. - (void)fire {  
  46.   self.block();  
  47. }  
  48.   
  49.   
  50. @end

猜你喜欢

转载自blog.csdn.net/love_coders/article/details/45727533