实现代码:
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
若发现有不合适或错误之处,还请批评指正,不胜感激。