ios GCD的使用及封装

时间:2023-01-07 05:14:47

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装

ios GCD的使用及封装


实现代码:

CGDHelper

  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

 

  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
用法举例:

一、基本概念举例:

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

 


二、基本用法举例

例子1:

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

 

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

 

三、GCD实际应用举例

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

 

1     #import <Foundation/Foundation.h>  
2
3 @interface NetGuarder : NSObject
4
5 + (NetGuarder *) shareNetGuarder;
6
7 @end
 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
1 #import <UIKit/UIKit.h>  
2
3 @interface URLConViewController : UIViewController <NSURLConnectionDataDelegate>
4 {
5 IBOutlet UISegmentedControl *segment;
6 IBOutlet UILabel *label;
7 }
8
9 @end
  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
 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

 

    #import "RNTimer.h"  

@interface RNTimer ()
@property (nonatomic, readwrite, copy) dispatch_block_t block;
@property (nonatomic, readwrite, assign) dispatch_source_t source;
@end

@implementation RNTimer
@synthesize block = _block;
@synthesize source = _source;

+ (RNTimer *)repeatingTimerWithTimeInterval:(NSTimeInterval)seconds
block:(
void (^)(void))block {
NSParameterAssert(seconds);
NSParameterAssert(block);

RNTimer
*timer = [[self alloc] init];
timer.block
= block;
timer.source
= dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0,
dispatch_get_main_queue());

uint64_t nsec
= (uint64_t)(seconds * NSEC_PER_SEC);
dispatch_source_set_timer(timer.source,
dispatch_time(DISPATCH_TIME_NOW, nsec),
nsec,
0);
dispatch_source_set_event_handler(timer.source, block);
dispatch_resume(timer.source);
return timer;
}

- (void)invalidate {
if (self.source) {
dispatch_source_cancel(self.source);
dispatch_release(self.source);
self.source
= nil;
}
self.block
= nil;
}

- (void)dealloc {
[self invalidate];
}

- (void)fire {
self.block();
}


@end


完整的项目链接:http://pan.baidu.com/share/link?shareid=386371&uk=3674861929

转载请保留,原文链接:http://write.blog.csdn.net/postedit/8708667

若发现有不合适或错误之处,还请批评指正,不胜感激。