实现代码:

CGDHelper

 /*
* Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。
* 系统要求:iOS4.0以上。
*/ #import <Foundation/Foundation.h> /////////////////////////////////////// enum 声明 ///////////////////////////////////////////////// //队列优先级
typedef enum
{
GlobalQueuePriorityDefault = ,
GlobalQueuePriorityHigh = ,
GlobalQueuePriorityLow = -,
GlobalQueuePriorityBackground = INT16_MIN } GlobalQueuePriority; //阻塞、非阻塞
typedef enum
{
PerformBlockFeatureChoke,
PerformBlockFeatureUnchoke } PerformBlockFeature; //网络请求方法
typedef enum GCDHelperHttpRequestMethod
{
GCDHelperHttpRequestMethodGET = ,
GCDHelperHttpRequestMethodPOST } GCDHelperHttpRequestMethod; /////////////////////////////////////// Block 声明 ///////////////////////////////////////////////// //返回值void
typedef void (^GCDBlock) (void);
typedef void (^GCDBlock1_Size_t) (size_t index);
typedef void (^GCDBlock1_Int) (int index);
typedef void (^GCDBlock1_Bool) (BOOL flag);
typedef void (^GCDBlock1_Float) (float index);
typedef void (^GCDBlock1_Obj) (id object); //返回值void,两个形式参数
typedef void (^GCDBlock2) (id object1, size_t index);
typedef void (^GCDBlock2_Obj_Int) (id object1, int index);
typedef void (^GCDBlock2_Obj_Obj) (id object1, id object2); //有返回值
typedef id (^GCD_Obj_Block_Obj) (id object);
typedef id (^GCD_Obj_Block_Void) (void); typedef void (^GCDHttpRequestBlock) (NSURLResponse *response, NSError *error, NSData *data); /////////////////////////////////////// GCDHelper 声明 ///////////////////////////////////////////////// @interface GCDHelper : NSObject /* 获取3种队列 */
+ (dispatch_queue_t) gcdMainQueue;
+ (dispatch_queue_t) gcdGlobalQueue:(GlobalQueuePriority) priority;
+ (dispatch_queue_t) gcdCustomQueue:(NSString *) queueName; //后台执行
+ (void) gcdPerformBlockAsynchronous:(GCDBlock) block; //后台获取数据后,回到主线程
+ (void) gcdPerformBlockAsynchronous:(GCDBlock) blockAsyn
finishOnMainQueue:(GCDBlock) blockM; /* 3种队列上执行Block
*
* 是否阻塞执行:(PerformBlockFeature) feature
* 全局队列优先级:(GlobalQueuePriority) priority
*/
+ (void) gcdPerformBlockOnMainQueue:(GCDBlock) block feature:(PerformBlockFeature) feature; + (void) gcdPerformBlockOnGlobalQueue:(GCDBlock) block
feature:(PerformBlockFeature) feature
priority:(GlobalQueuePriority) priority; + (void) gcdPerformBlockOnCustomQueue:(GCDBlock) block
feature:(PerformBlockFeature) feature
name:(NSString *) queueName; //延迟执行方法
+ (void) gcdPerformBlock:(GCDBlock) block
onQueue:(dispatch_queue_t) queue
delaySecond:(int64_t) second; //只执行一次
+ (void) gcdPerformBlockOnce:(GCDBlock) block; //并发
+ (void) gcdBatchPerformBlocks:(NSArray *) blockArray finally:(GCDBlock) finallyBlock; + (void) gcdBatchPerformBlockWithData:(NSArray *) dataArray
maxConcurrentOperationCount:(uint) count
handleBlock:(GCDBlock1_Obj) block
finally:(GCDBlock1_Obj) finallyBlock; @end /////////////////////////////////////// 图片下载 ///////////////////////////////////////////////// @interface GCDHelper (ImageDownload) - (void) gcdImageWithURLString:(NSString *) URLString;
- (void) gcdImageWithURLString:(NSString *) URLString completion:(GCDBlock2_Obj_Obj) completion; @end /////////////////////////////////////// 网络请求 ///////////////////////////////////////////////// GCDBlock1_Bool _netWorkBlock;
@interface GCDHelper (NetworkConnect) //网络连接判断、实时监控
- (void) gcdNetWorkGuarder:(NSString *) hostname withBlock:(GCDBlock1_Bool) block; @end @interface GCDHelper (HttpRequest) //GCD请求网络(GET方式测试通过,POST方式测试未通过)
- (void) gcdHttpRequestWithURL:(NSString *) URLString
httpMethod:(GCDHelperHttpRequestMethod) method
params:(NSDictionary *) params
timeout:(NSTimeInterval) time
success:(GCDHttpRequestBlock) successBlock
fail:(GCDHttpRequestBlock) failBlock; @end
 #import "GCDHelper.h"  

 #import <SystemConfiguration/SystemConfiguration.h>  

 #import <sys/socket.h>
#import <netinet/in.h>
#import <netinet6/in6.h>
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h> //Error
#define GCDHelperErrorURLISNULL [NSError errorWithDomain:@"please setup GCDHelper‘s url or urlString" code:100 userInfo:nil]
#define GCDHelperErrorRequestISNULL [NSError errorWithDomain:@"request can not be nil!" code:101 userInfo:nil]
#define GCDHelperErrorFileExist [NSError errorWithDomain:@"File Exist!" code:102 userInfo:nil]
#define GCDHelperErrorCreateFail [NSError errorWithDomain:@"Create File Fail!" code:103 userInfo:nil] //下载的临时文件的后缀
#define kTHDownLoadTask_TempSuffix @".TempDownload"
//计算下载速度的取样时间
#define kTHDownLoadTimerInterval 2.0
//THDispatchQueue默认的并发数
#define kTHDispatchQueueDefaultConcurrentCount 10 #define kDefaultTimeoutInterval 15 static NSString * const BOUNDRY = @"--------------------------7d71a819230404"; @implementation GCDHelper - (void) dealloc
{
[super dealloc];
} - (id) init
{
if (self = [super init])
{
} return self;
} #pragma mark -
#pragma mark 获取队列 + (dispatch_queue_t) gcdMainQueue
{
return dispatch_get_main_queue();
} + (dispatch_queue_t) gcdGlobalQueue:(GlobalQueuePriority) priority
{
switch (priority)
{
case GlobalQueuePriorityDefault:
return dispatch_get_global_queue(priority, );
break;
case GlobalQueuePriorityHigh:
return dispatch_get_global_queue(priority, );
break;
case GlobalQueuePriorityLow:
return dispatch_get_global_queue(priority, );
break;
case GlobalQueuePriorityBackground:
return dispatch_get_global_queue(priority, );
break; default:
return dispatch_get_global_queue(GlobalQueuePriorityDefault, );
break;
}
} + (dispatch_queue_t) gcdCustomQueue:(NSString *) queueName;
{
return dispatch_queue_create([queueName UTF8String], NULL);
} #pragma mark -
#pragma mark 3种队列上执行Block + (void) gcdPerformBlockOnMainQueue:(GCDBlock) block feature:(PerformBlockFeature) feature
{
switch (feature)
{
case PerformBlockFeatureChoke:
dispatch_sync([GCDHelper gcdMainQueue], block);
break; case PerformBlockFeatureUnchoke:
dispatch_async([GCDHelper gcdMainQueue], block);
break; default:
dispatch_sync([GCDHelper gcdMainQueue], block);
break;
}
} + (void) gcdPerformBlockOnGlobalQueue:(GCDBlock) block feature:(PerformBlockFeature) feature priority:(GlobalQueuePriority) priority
{
switch (feature)
{
case PerformBlockFeatureChoke:
dispatch_sync([GCDHelper gcdGlobalQueue:priority], block);
break; case PerformBlockFeatureUnchoke:
dispatch_async([GCDHelper gcdGlobalQueue:priority], block);
break; default:
dispatch_sync([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], block);
break;
}
} + (void) gcdPerformBlockOnCustomQueue:(GCDBlock) block feature:(PerformBlockFeature) feature name:(NSString *) queueName
{
switch (feature)
{
case PerformBlockFeatureChoke:
dispatch_sync([GCDHelper gcdCustomQueue:queueName], block);
break; case PerformBlockFeatureUnchoke:
dispatch_async([GCDHelper gcdCustomQueue:queueName], block);
break; default:
dispatch_sync([GCDHelper gcdCustomQueue:@"com.GCDHelper.Queue"], block);
break;
}
} //后台执行
+ (void) gcdPerformBlockAsynchronous:(GCDBlock) block
{
[GCDHelper gcdPerformBlockOnGlobalQueue:block
feature:PerformBlockFeatureUnchoke
priority:GlobalQueuePriorityDefault];
} //后台获取数据后,回到主线程
+ (void) gcdPerformBlockAsynchronous:(GCDBlock) blockAsyn
finishOnMainQueue:(GCDBlock) blockM
{
dispatch_async([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], ^{
blockAsyn();
dispatch_async([GCDHelper gcdMainQueue], ^{
blockM();
});
});
} #pragma mark -
#pragma mark 队列延迟时间执行方法
+ (void) gcdPerformBlock:(GCDBlock) block onQueue:(dispatch_queue_t) queue delaySecond:(int64_t) second
{
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, second * NSEC_PER_SEC);
dispatch_after(popTime, queue, block);
} #pragma mark -
#pragma mark 只执行一次 + (void) gcdPerformBlockOnce:(GCDBlock) block
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, block);
} #pragma mark -
#pragma mark 无序并发 + (void) gcdBatchPerformBlocks:(NSArray *) blockArray finally:(GCDBlock) finallyBlock
{
[blockArray retain]; dispatch_queue_t queue = [GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault];
dispatch_group_t group = dispatch_group_create(); for(GCDBlock block in blockArray)
{
dispatch_group_async(group, queue, ^{
block();
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_async([GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault], ^{
finallyBlock();
}); dispatch_release(group); [blockArray release];
} + (void) gcdBatchPerformBlockWithData:(NSArray *) dataArray
maxConcurrentOperationCount:(uint) count
handleBlock:(GCDBlock1_Obj) block
finally:(GCDBlock1_Obj) finallyBlock
{
[dataArray retain]; dispatch_queue_t queue = [GCDHelper gcdGlobalQueue:GlobalQueuePriorityDefault];
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create(count);
for(id obj in dataArray)
{
NSLog(@"并发中");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
block(obj);
dispatch_semaphore_signal(semaphore);
});
} dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, queue, ^{
finallyBlock(dataArray);
});
dispatch_release(group); [dataArray release];
} #pragma mark -
#pragma mark 图片下载 - (void) gcdImageWithURLString:(NSString *) URLString
{
[self gcdImageWithURLString:URLString completion:nil];
} - (void) gcdImageWithURLString:(NSString *) URLString completion:(GCDBlock2_Obj_Obj) completion
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{ NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:URLString]];
[request setHTTPMethod:@"GET"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:nil];
[request release]; UIImage *image = [UIImage imageWithData:returnData]; if (image)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
completion(image, URLString);
});
} else
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
completion(image, URLString);
});
}
});
} @end #pragma mark -
#pragma mark 网络部分 @implementation GCDHelper (NetworkConnect) - (BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
{
BOOL connectionUP = YES; if(!(flags & kSCNetworkReachabilityFlagsReachable))
connectionUP = NO; if( (flags & (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)) == (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) )
connectionUP = NO; return connectionUP;
} -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
{
dispatch_async(dispatch_get_main_queue(), ^{
_netWorkBlock([self isReachableWithFlags:flags]);
});
} static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
{
@autoreleasepool
{
[(GCDHelper *)info reachabilityChanged:flags];
}
} - (void) gcdNetWorkGuarder:(NSString *) hostname withBlock:(GCDBlock1_Bool) block
{
_netWorkBlock = block; SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
SCNetworkReachabilityContext context = { , NULL, NULL, NULL, NULL };
dispatch_queue_t queue = dispatch_queue_create("com.myself.reachability", NULL);
context.info = (void *)self;
SCNetworkReachabilitySetCallback(ref, TMReachabilityCallback, &context);
SCNetworkReachabilitySetDispatchQueue(ref, queue);
} @end @implementation GCDHelper(HttpRequest) - (void) startPOSTHTTPRequest:(NSString *) URLString
params:(NSDictionary *) params
timeout:(NSTimeInterval) time
success:(GCDHttpRequestBlock) successBlock
fail:(GCDHttpRequestBlock) failBlock
{
[params retain];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{ __block NSURLResponse *response = nil;
__block NSError *error = nil;
__block NSData *receiveData = nil; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:[URLString lowercaseString]]];
[request setHTTPMethod:@"POST"];
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[request setTimeoutInterval:time]; if (!request)
{
NSDictionary *errorInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"发送请求失败", @"errorKey", nil];
error = [NSError errorWithDomain:@"www.myself.com" code: userInfo:errorInfo]; dispatch_async(dispatch_get_main_queue(), ^{
successBlock(response, error, receiveData);
}); return;
} if (params != nil)
{
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", BOUNDRY]
forHTTPHeaderField:@"Content-Type"]; int len=;
NSMutableData *postData =[NSMutableData dataWithCapacity:len];
[postData appendData:[[NSString stringWithFormat:@"--%@/r/n", BOUNDRY]
dataUsingEncoding:NSUTF8StringEncoding]];
int i=;
int cnt = [params count]; for (NSString *key in [params allKeys])
{
// NSString *str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"/r/n/r/n", key];
[postData appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"/r/n/r/n", key] dataUsingEncoding:NSUTF8StringEncoding]]; [postData appendData: [[NSString stringWithFormat:@"%@",[params objectForKey:key]]
dataUsingEncoding:NSUTF8StringEncoding]];
if(i != cnt - )
{
[postData appendData:[[NSString stringWithFormat:@"/r/n--%@/r/n", BOUNDRY]
dataUsingEncoding:NSUTF8StringEncoding]];
}
i++ ;
}
[postData appendData:[[NSString stringWithFormat:@"/r/n--%@--/r/n", BOUNDRY]
dataUsingEncoding:NSUTF8StringEncoding]]; [request setHTTPBody:postData];
} receiveData = [[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] retain];
if (!error)
{
dispatch_async(dispatch_get_main_queue(), ^{
successBlock(response, nil, receiveData);
});
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
successBlock(response, error, receiveData);
});
} [request release];
}); [params release];
} - (void) startGETHTTPRequest:(NSString *) URLString
params:(NSDictionary *) params
timeout:(NSTimeInterval) time
success:(GCDHttpRequestBlock) successBlock
fail:(GCDHttpRequestBlock) failBlock
{
[params retain]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
__block NSURLResponse *response = nil;
__block NSError *error = nil;
__block NSData *receiveData = nil; NSMutableString *paramsString = [[NSMutableString alloc] init];
for(NSString *key in params)
{
[paramsString appendFormat:@"&%@=%@", key, [params objectForKey:key]];
}
NSString *requestString = [[NSString alloc] initWithFormat:@"%@%@", URLString, paramsString];
NSURL *reqUrl = [[NSURL alloc] initWithString:requestString]; [paramsString release];
[requestString release]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:reqUrl];
[request setHTTPMethod:@"GET"];
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[request setTimeoutInterval:time]; [reqUrl release]; if (request)
{
receiveData = [[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] retain];
} if (!error)
{
dispatch_async(dispatch_get_main_queue(), ^{
successBlock(response, nil, receiveData);
});
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
successBlock(response, error, receiveData);
});
} [request release];
}); [params release];
} - (void) gcdHttpRequestWithURL:(NSString *) URLString
httpMethod:(GCDHelperHttpRequestMethod) method
params:(NSDictionary *) params
timeout:(NSTimeInterval) time
success:(GCDHttpRequestBlock) successBlock
fail:(GCDHttpRequestBlock) failBlock
{
switch (method)
{
case GCDHelperHttpRequestMethodGET:
{
[self startGETHTTPRequest:URLString params:params timeout:time success:successBlock fail:failBlock];
break;
}
case GCDHelperHttpRequestMethodPOST:
{
[self startPOSTHTTPRequest:URLString params:params timeout:time success:successBlock fail:failBlock];
break;
} default:
break;
}
} @end

用法举例:

一、基本概念举例:

 [cpp] view plaincopyprint?

     #import <UIKit/UIKit.h>  

     @interface BaseViewController : UIViewController
{
IBOutlet UITextField *field1;
IBOutlet UITextField *field2;
IBOutlet UITextField *field3; IBOutlet UITextField *textField; dispatch_queue_t queue;
} - (IBAction) calculate:(id)sender;
- (IBAction) operationQueue:(id)sender;
- (IBAction) gcd:(id)sender; - (IBAction) notchoke:(id)sender;
- (IBAction) choke:(id)sender; - (IBAction) getUIData:(id)sender; - (IBAction)startQueue:(id)sender;
- (IBAction)suspendQueue:(id)sender;
- (IBAction)resumeQueue:(id)sender; @end [cpp] view plaincopyprint? #import "BaseViewController.h" @implementation BaseViewController - (void) dealloc
{
dispatch_release(queue); [super dealloc];
} - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
queue = dispatch_queue_create("sss", NULL);
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
} - (void) longTask:(id) sender
{
NSMutableArray *arr = [NSMutableArray array];
for (int i = ; i < ; i++) { [arr addObject:[NSMutableArray arrayWithObject:@(i)]];
NSLog(@"longTask:%d", i);
}
} - (void) longTaskOther:(id) sender
{
NSMutableArray *arr = [NSMutableArray array];
for (int i = ; i < ; i++) { [arr addObject:[NSMutableArray arrayWithObject:@(i)]];
NSLog(@"longTaskOther:%d", i);
}
} - (IBAction) calculate:(id)sender
{
field3.text = [NSString stringWithFormat:@"%f", [field1.text floatValue] - [field2.text floatValue]];
}
- (IBAction) operationQueue:(id)sender;
{
NSOperationQueue *aqueue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(longTask:)
object:nil];
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(longTaskOther:)
object:nil]; [aqueue addOperation:operation];
[aqueue addOperation:operation1]; [operation release];
[operation1 release];
}
- (IBAction) gcd:(id)sender //3.192999
{
[GCDHelper gcdPerformBlockAsynchronous:^{
NSMutableArray *arr = [NSMutableArray array];
for (int i = ; i < ; i++) { [arr addObject:[NSMutableArray arrayWithObject:@(i)]];
NSLog(@"longTask:%d", i);
}
}]; [GCDHelper gcdPerformBlockAsynchronous:^{
NSMutableArray *arr = [NSMutableArray array];
for (int i = ; i < ; i++) { [arr addObject:[NSMutableArray arrayWithObject:@(i)]];
NSLog(@"longTaskOther:%d", i);
}
}];
} ////////////////////////////////////////////////////// - (IBAction)notchoke:(id)sender
{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"qqq");
}); NSLog(@"不阻塞");
} //Calls to dispatch_sync() targeting the current queue will result
//* in dead-lock. Use of dispatch_sync() is also subject to the same
//* multi-party dead-lock problems that may result from the use of a mutex.
//* Use of dispatch_async() is preferred.
//在当前队列上调用dispatch_sync() 会导致死锁。调用dispatch_sync(),并使用mutex 经常会导致多方死锁问题。
- (IBAction) choke:(id)sender
{
dispatch_queue_t exampleQueue; int i = ;
switch (i) {
case :
exampleQueue = dispatch_get_global_queue(, );
break;
case :
exampleQueue = dispatch_queue_create("com.abc.xxx", NULL);
break;
case :
exampleQueue = dispatch_get_current_queue();
break;
case :
exampleQueue = dispatch_get_main_queue();
break; default:
exampleQueue = dispatch_get_global_queue(, );
break;
} dispatch_sync( exampleQueue,^{
[self longTask:nil];
}); NSLog(@"task finish");
} - (IBAction) getUIData:(id)sender
{
dispatch_async(dispatch_get_global_queue(, ), ^{ __block NSString *stringValue;
dispatch_sync(dispatch_get_main_queue(), ^{
stringValue = [textField.text copy];
}); [stringValue retain]; NSLog(@"stringValue:%@", stringValue);
});
} //一个要注意的地方是,dispatch queue的挂起是block粒度的。换句话说,挂起一个queue并不会将当前正在执行的block挂起。它会允许当前执行的block执行完毕,然后后续的block不再会被执行,直至queue被恢复。
//还有一个注意点:从man页上得来的:如果你挂起了一个queue或者source,那么销毁它之前,必须先对其进行恢复。
- (IBAction)startQueue:(id)sender
{
dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"taskA");
}
}); dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"taskB");
}
}); dispatch_async(queue, ^{
for (int i = ; i < ; i++) {
NSLog(@"taskC");
}
});
}
- (IBAction)suspendQueue:(id)sender
{
NSLog(@"Queue suspend");
dispatch_suspend(queue); }
- (IBAction)resumeQueue:(id)sender
{
NSLog(@"Queue resume");
dispatch_resume(queue); }

二、基本用法举例

例子1:

     #import <UIKit/UIKit.h>  

     @interface OneViewController : UIViewController  

     //无序并发
- (IBAction)selector0:(id)sender; //无序并发处理数据
- (IBAction)selector100:(id)sender; //执行一次
- (IBAction)selector1:(id)sender; //异步/后台执行
- (IBAction)selector2:(id)sender; //后台执行,然后返回主线程
- (IBAction)selector3:(id)sender; //三种队列执行
- (IBAction)selector4:(UISegmentedControl *)sender; //延迟执行
- (IBAction)selector5:(id)sender; @end [cpp] view plaincopyprint? #import "OneViewController.h" @interface OneViewController () @end @implementation OneViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad];
} - (NSMutableArray *) getBlockArray
{
NSMutableArray *arr = [[NSMutableArray array] retain]; GCDBlock b0 = ^{ NSLog(@"无序并发: 0"); sleep(); }; [arr addObject:b0];
GCDBlock b1 = ^{ NSLog(@"无序并发: 1"); }; [arr addObject:b1];
GCDBlock b2 = ^{ NSLog(@"无序并发: 2"); }; [arr addObject:b2];
GCDBlock b3 = ^{ NSLog(@"无序并发: 3"); }; [arr addObject:b3];
GCDBlock b4 = ^{ NSLog(@"无序并发: 4"); }; [arr addObject:b4];
GCDBlock b5 = ^{ NSLog(@"无序并发: 5"); }; [arr addObject:b5];
GCDBlock b6 = ^{ NSLog(@"无序并发: 6"); }; [arr addObject:b6];
GCDBlock b7 = ^{ NSLog(@"无序并发: 7"); }; [arr addObject:b7];
GCDBlock b8 = ^{ NSLog(@"无序并发: 8"); }; [arr addObject:b8];
GCDBlock b9 = ^{ NSLog(@"无序并发: 9"); }; [arr addObject:b9];
GCDBlock b10 = ^{ NSLog(@"无序并发: 10"); }; [arr addObject:b10];
GCDBlock b11 = ^{ NSLog(@"无序并发: 11"); }; [arr addObject:b11];
GCDBlock b12 = ^{ NSLog(@"无序并发: 12"); }; [arr addObject:b12];
GCDBlock b13 = ^{ NSLog(@"无序并发: 13"); }; [arr addObject:b13];
GCDBlock b14 = ^{ NSLog(@"无序并发: 14"); }; [arr addObject:b14];
GCDBlock b15 = ^{ NSLog(@"无序并发: 15"); }; [arr addObject:b15]; return arr;
} //无序并发
- (IBAction)selector0:(id)sender
{
[GCDHelper gcdBatchPerformBlocks:[self getBlockArray] finally:^{
NSLog(@"一组有序并发完成");
}]; // NSLog(@"一组无序并发完成");
} - (IBAction)selector100:(id)sender
{
NSMutableArray *arr = [NSMutableArray array];
for (int i = ; i < ; i++) {
[arr addObject:[NSMutableArray array]];
} __block int i = ;
[GCDHelper gcdBatchPerformBlockWithData:arr maxConcurrentOperationCount: handleBlock:^(id object) { sleep();
NSMutableArray *arr = (NSMutableArray *)object;
[arr addObject:@(i)];
i++;
} finally:^(id object) {
NSLog(@"arr:%@", object);
}];
} - (IBAction)selector1:(id)sender
{
[GCDHelper gcdPerformBlockOnce:^{
NSLog(@"别想让我执行第二次");
}];
NSLog(@"不执行~");
} //异步/后台执行
- (IBAction)selector2:(id)sender
{
[GCDHelper gcdPerformBlockAsynchronous:^{
sleep();
NSLog(@"全局队列执行完成");
}];
NSLog(@"全局队列执行,不影响主队列");
} //后台执行,然后返回主线程
- (IBAction)selector3:(id)sender
{
[GCDHelper gcdPerformBlockAsynchronous:^{ for (int i = ; i< ; i++)
{
NSLog(@"全局队列执行: %d", i);
} } finishOnMainQueue:^{
NSLog(@"回到主队列");
}];
} //三种队列执行
- (IBAction)selector4:(UISegmentedControl *)sender
{
switch (sender.selectedSegmentIndex) {
case :
{
[GCDHelper gcdPerformBlockOnMainQueue:^{
NSLog(@"主队列执行");
} feature:PerformBlockFeatureUnchoke];
break;
}
case :
{
[GCDHelper gcdPerformBlockOnGlobalQueue:^{
NSLog(@"全局队列执行");
} feature:PerformBlockFeatureUnchoke priority:GlobalQueuePriorityDefault];
break;
}
case :
{
[GCDHelper gcdPerformBlockOnCustomQueue:^{
NSLog(@"自创建队列执行");
} feature:PerformBlockFeatureUnchoke name:@"com.abc.bcd"];
break;
} default:
break;
}
} //延迟执行
- (IBAction)selector5:(id)sender
{
NSLog(@"延迟 2s 执行");
[GCDHelper gcdPerformBlock:^{
NSLog(@"执行完毕");
} onQueue:[GCDHelper gcdMainQueue] delaySecond:];
} @end
     #import <UIKit/UIKit.h>  

     @interface MulthreadConcurrentVC : UIViewController  

     @end  

 [cpp] view plaincopyprint?

     #import "MulthreadConcurrentVC.h"  

     /* 

      如何在GCD中快速的控制并发呢?答案就是
dispatch_semaphore,对经常做unix开发的人来讲,我所介绍的内容可能就显得非常入门级了,信号量在他们的多线程开发中再平常不过了。
在GCD中有三个函数是semaphore的操作,分别是:
dispatch_semaphore_create 创建一个semaphore
dispatch_semaphore_signal 发送一个信号
dispatch_semaphore_wait 等待信号
简单的介绍一下这三个函数,第一个函数有一个整形的参数,我们可以理解为信号的总量,dispatch_semaphore_signal是发送一个信号,自然会让信号总量加1,dispatch_semaphore_wait等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量减少1,根据这样的原理,我们便可以快速的创建一个并发控制。 */ /* 简单的介绍一下这一段代码,创建了一个初使值为10的semaphore,每一次for循环都会创建一个新的线程,线程结束的时候会发送一个信号,线程创建之前会信号等待,所以当同时创建了10个线程之后,for循环就会阻塞,等待有线程结束之后会增加一个信号才继续执行,如此就形成了对并发的控制,如上就是一个并发数为10的一个线程队列。 */ @implementation MulthreadConcurrentVC - (void) loadView
{
[super loadView];
} - (void)aSelector:(id)sender
{
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t semaphore = dispatch_semaphore_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
for (int i = ; i < ; i++)
{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_group_async(group, queue, ^{
NSLog(@"%i",i);
sleep();
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
dispatch_release(semaphore);
} - (void)viewDidLoad
{
[super viewDidLoad]; UIButton *bt = [UIButton buttonWithType:UIButtonTypeRoundedRect];
bt.frame = CGRectMake(, , , );
[bt addTarget:self action:@selector(aSelector:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:bt];
}

三、GCD实际应用举例

     #import <UIKit/UIKit.h>  

     #import "GCDHelper.h"  

     @interface TableViewController : UITableViewController  

     @end  

 [cpp] view plaincopyprint?

     #import "TableViewController.h"
#import "CustomCell.h"
#import <objc/runtime.h> static char * const kIndexPathAssociationKey = "JK_indexPath"; @interface TableViewController () @end @implementation TableViewController - (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad]; self.clearsSelectionOnViewWillAppear = NO;
self.navigationItem.rightBarButtonItem = self.editButtonItem;
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return ;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return ;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UIImageView *im = [[UIImageView alloc] initWithFrame:CGRectMake(, , , )];
im.tag = ;
[cell addSubview:im];
[im release];
} return cell;
} - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// http://localhost:8888/Imgs/img0.png
// http://theme.blogcn.com/wp-content/themes/coffee-desk/images/rsscoffee.PNG NSString *imgURLStr = nil;
if ((indexPath.row % ) == )
{
imgURLStr = @"http://localhost:8888/Imgs/img0.png";
} else
{
imgURLStr = @"http://localhost:8888/Imgs/img1.png";
} GCDHelper *hp = [GCDHelper new];
[hp gcdImageWithURLString:imgURLStr
completion:^(id object1, id object2) { dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[(UIImageView *)[cell viewWithTag:] setImage:(UIImage *)object1];
});
}];
} #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
} #pragma mark -
#pragma mark - cell重用 - (void)tableViewCellIsPreparingForReuse:(NSNotification *)notification
{
if ([[notification object] isKindOfClass:[CustomCell class]]) {
CustomCell *cell = (CustomCell *)[notification object]; objc_setAssociatedObject(cell,
kIndexPathAssociationKey,
nil,
OBJC_ASSOCIATION_RETAIN); [[cell imageView] setImage:nil];
}
} @end
     #import <UIKit/UIKit.h>  

     extern NSString * const kJKPrepareForReuseNotification;  

     @interface CustomCell : UITableViewCell  

     @end  

 [cpp] view plaincopyprint?

     #import "CustomCell.h"  

     NSString * const kJKPrepareForReuseNotification = @"JKCallbacksTableViewCell_PrepareForReuse";  

     @implementation CustomCell  

     - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//如果cell 的图片发生改变,当cell重用的时候,刷新图片 [[self imageView] addObserver:self
forKeyPath:@"image"
options:NSKeyValueObservingOptionOld
context:NULL];
}
return self;
} - (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(@"observeValueForKeyPath"); if (object == [self imageView] &&
[keyPath isEqualToString:@"image"] &&
([change objectForKey:NSKeyValueChangeOldKey] == nil ||
[change objectForKey:NSKeyValueChangeOldKey] == [NSNull null]))
{
[self setNeedsLayout];
}
} - (void)prepareForReuse
{
[[NSNotificationCenter defaultCenter] postNotificationName:kJKPrepareForReuseNotification
object:self]; [super prepareForReuse];
}
     #import <Foundation/Foundation.h>  

     @interface NetGuarder : NSObject  

     + (NetGuarder *) shareNetGuarder;  

     @end  
     #import "NetGuarder.h"  

     @implementation NetGuarder  

     static NetGuarder *guarder = nil;  

     + (void) getNetConnectMsg
{
GCDHelper *hp = [GCDHelper new];
[hp gcdNetWorkGuarder:@"www.baidu.com" withBlock:^(BOOL flag) {
if (flag)
{
NSLog(@"Net connect");
} else
{
NSLog(@"Net not connect");
}
}];
} + (NetGuarder *) shareNetGuarder
{
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{ NSLog(@"单例创建");
guarder = [[self alloc] init]; [NetGuarder getNetConnectMsg];
}); return guarder;
} @end
 #import <UIKit/UIKit.h>  

 @interface URLConViewController : UIViewController <NSURLConnectionDataDelegate>
{
IBOutlet UISegmentedControl *segment;
IBOutlet UILabel *label;
} @end
     #import "URLConViewController.h"  

     typedef struct _INT
{
int t1; }INT_STRUCT; @interface URLConViewController ()
{
NSMutableData *receivedData;
BOOL finished;
} @end @implementation URLConViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
receivedData = [[NSMutableData data] retain];
}
return self;
} - (void)viewDidLoad
{
[super viewDidLoad];
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
} - (void) cleanText
{
label.text = @"";
} - (IBAction)segmentAction:(UISegmentedControl *)sender
{
switch (sender.selectedSegmentIndex) {
case :
{
[self sendRequestSync];
break;
}
case :
{
[self sendRequestAsync];
break;
}
case :
{
[self sendRequestAsyncOther];
break;
}
case :
{
[self gcdRequest];
break;
} default:
break;
}
} #pragma mark -
#pragma mark GCDRequest - (void) gcdRequest
{
GCDHelper *hp = [GCDHelper new]; [hp gcdHttpRequestWithURL:@"http://localhost:8888/test.php"
httpMethod:GCDHelperHttpRequestMethodGET
params:[NSDictionary dictionary]
timeout:5.0f
success:^(NSURLResponse *response, NSError *error, NSData *data) {
if (data && (!error))
{
label.text = [[data objectFromJSONData] description];
} }
fail:^(NSURLResponse *response, NSError *error, NSData *data) {
if (error)
{
label.text = [error description];
}
}];
} #pragma mark -
#pragma mark sendRequestSync - (void) sendRequestSync
{
[self cleanText]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:@"http://localhost:8888/test.php"]];
[request setHTTPMethod:@"GET"]; NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:&error]; if (data && (!error))
{
label.text = [[data objectFromJSONData] description];
}
} #pragma mark -
#pragma mark sendRequestAsync - (void) sendRequestAsync
{
finished = NO; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://localhost:8888/test1.php"]];
[request setHTTPMethod:@"GET"];
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[request setTimeoutInterval:5.0f]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:YES]; [connection start]; // 但是异步模式下带来了一个新的问题,很多情况下,网络请求不在主线程,或者界面等待网络结果,不在主线程的时候,调用线程如果生命周期over,下面这些可能都没有调用到,导致得不到想要得效果,所以需要在NSURLConnection请求后面加点东西来阻塞
while(!finished) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; }
} // 收到回应
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// 注意这里将NSURLResponse对象转换成NSHTTPURLResponse对象才能去
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; if ([response respondsToSelector:@selector(allHeaderFields)])
{
NSDictionary *dictionary = [httpResponse allHeaderFields];
NSLog(@"allHeaderFields: %@",dictionary);
}
[receivedData setLength:];
} // 接收数据
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"get some data");
[receivedData appendData:data];
} // 数据接收完毕
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *results = [[NSString alloc] initWithBytes:[receivedData bytes]
length:[receivedData length]
encoding:NSUTF8StringEncoding]; label.text = [[results objectFromJSONString] description]; finished = YES;
} // 返回错误
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"Connection failed: %@", error);
} #pragma mark -
#pragma mark sendRequestAsyncOther - (IBAction) sendRequestAsyncOther
{
[self cleanText]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://localhost:8888/test2.php"]];
[request setHTTPMethod:@"GET"];
[request setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[request setTimeoutInterval:5.0f]; [NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue new]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{
label.text = [[data objectFromJSONData] description];
}); }];
} @end
     #import <Foundation/Foundation.h>  

     /** Simple GCD-based timer based on NSTimer. 

      Starts immediately and stops when deallocated. This avoids many of the typical problems with NSTimer: 

      * RNTimer runs in all modes (unlike NSTimer)
* RNTimer runs when there is no runloop (unlike NSTimer)
* Repeating RNTimers can easily avoid retain loops (unlike NSTimer)
*/ @interface RNTimer : NSObject /**---------------------------------------------------------------------------------------
@name Creating a Timer
-----------------------------------------------------------------------------------------
*/ /** Creates and returns a new repeating RNTimer object and starts running it After `seconds` seconds have elapsed, the timer fires, executing the block.
You will generally need to use a weakSelf pointer to avoid a retain loop.
The timer is attached to the main GCD queue. @param seconds The number of seconds between firings of the timer. Must be greater than 0.
@param block Block to execute. Must be non-nil @return A new RNTimer object, configured according to the specified parameters.
*/
+ (RNTimer *)repeatingTimerWithTimeInterval:(NSTimeInterval)seconds block:(dispatch_block_t)block; /**---------------------------------------------------------------------------------------
@name Firing a Timer
-----------------------------------------------------------------------------------------
*/ /** Causes the block to be executed. This does not modify the timer. It will still fire on schedule.
*/
- (void)fire; /**---------------------------------------------------------------------------------------
@name Stopping a Timer
-----------------------------------------------------------------------------------------
*/ /** Stops the receiver from ever firing again Once invalidated, a timer cannot be reused. */
- (void)invalidate;
@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,
, ,
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, );
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

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

 

ios GCD的使用及封装的更多相关文章

  1. iOS GCD基础篇 - 同步、异步,并发、并行的理解

    1.关于GCD - GCD全称是Grand Central Dispatch  - GCD是苹果公司为多核的并行运算提出的解决方案  - GCD会自动利用更多的CPU内核(比如双核.四核)  - GC ...

  2. iOS GCD之dispatch_semaphore(信号量)

    前言 最近在看AFNetworking3.0源码时,注意到在 AFURLSessionManager.m 里面的 tasksForKeyPath: 方法 (L681),dispatch_semapho ...

  3. iOS GCD NSOperation NSThread等多线程各种举例详解(拷贝)

    2年多的iOS之路匆匆而过,期间也拜读来不少大神的博客,近来突然为自己一直做伸手党感到羞耻,是时候回馈社会.回想当年自己还是小白的时候,照着一些iOS多线程教程学,也只是照抄,只知其然.不知其所以然. ...

  4. IOS GCD 使用 (二)

     上一节,主要介绍了GCD的基本的概念,这节将用代码深入详细介绍GCD的使用. 一  使用介绍    GCD的使用主要分为三步:创建代码块;选择或创建合适的分发队列;(同步.异步方式)向分发队列提交任 ...

  5. iOS——GCD多线程

    1> 概述 Grand Central Dispatch (GCD)是Apple开发的一种多核编程技术.主要用于优化应用程序以支持多核处理器以及其他对称多处理系统. GCD提供函数实现多线程开发 ...

  6. iOS GCD NSOperation NSThread等多线程各种举例详解

    废话就不多说,直接上干货.如下图列举了很多多线程的知识点,每个按钮都写有对应的详细例子,并对运行结果进行分析,绝对拿实践结果来说话.如果各位道友发现错误之处还请指正.附上demo下载地址

  7. iOS GCD 编程小结

    一.简单介绍 1.GCD简介? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD优势 GCD是苹果公司为多核的并行运算提出的 ...

  8. ios - GCD简单小结

    首先GCD两个名词: 队列 同步异步. 队列: 任务放到队列,队列中的任务执行方式取决于执行队列中任务的方式---同步异步. 串行队列: 任务顺序执行,可以叫阻塞队列.只有前面任务完成才执行后面的. ...

  9. iOS GCD 与 NSOperationQueue

    NSOperationQueue ios NSOperation vs. GCD StackOverflow: NSOperation vs. Grand Central Dispatch Blog: ...

随机推荐

  1. JS获取ckeditor4.x里的值

    项目中有这样一个需求,使用ckeditor可以上传图片,需要在前端验证一下不可上传多于5张图片. 以下是查看源代码所看到的ckeditor里的值 <p>AAAAA</p> &l ...

  2. 竞价广告系统-逻辑回归优化方法-L-BFGS

    逻辑回归优化方法-L-BFGS 逻辑回归的优化方法是一个经典的问题,如果我们把它视为一个最大熵模型,那么我们知道最早的优化方法是IIS,这个方法就不细讲了,因为它速度很慢.后来发现在最优化领域中非常常 ...

  3. Mahout之(三)相似性度量

    User CF 和 Item CF 都依赖于相似度的计算,因为只有通过衡量用户之间或物品之间的相似度,才能找到用户的“邻居”,才能完成推荐.上文简单的介绍了相似性的计算,但不完全,下面就对常用的相似度 ...

  4. iOS多线程的初步研究(六)

    iOS多线程的初步研究(六) iOS平台提供更高级的并发(异步)调用接口,让你可以集中精力去设计需完成的任务代码,避免去写与程序逻辑无关的线程生成.运行等管理代码.当然实质上是这些接口隐含生成线程和管 ...

  5. 前端基于easyui的mvc扩展(续)

    前端基于easyui的mvc扩展(续) 回顾及遗留问题 上一篇讲解了基于easyui的mvc扩展的基本实现,已经降低了在mvc内使用easyui的难度,但是仍然还有一些问题: 当我们要给生成的控件设置 ...

  6. JAXP进行DOM和SAX解析

    1.常用XML的解析方式:DOM和SAX 1)DOM思想:将整个XML加载内存中,形成文档对象,所以对XML操作都对内存中文档对象进行. 2)SAX思想:一边解析,一边处理,一边释放内存资源---不允 ...

  7. Log in Spring

    记录日志向来是企业级应用程序必须考虑的事情.早些年,一个项目一个日志功能或模块,然后有了log4j这样的产品.不知是log4j将记录日志做到了极致,或是技术含量不高,又或是经济利益不明显,它已成为了这 ...

  8. C#代码搜索器

    WEBUS2.0 In Action - [源代码] - C#代码搜索器 最近由于工作的需要, 要分析大量C#代码, 在数万个cs文件中搜索特定关键词. 这是一项非常耗时的工作, 用Notepad++ ...

  9. C#操作AD及Exchange Server总结

    C#操作AD及Exchange Server总结 这篇博客的目的:根据亲身项目经历,总结对AD及Exchange Server的操作,包括新建AD用户,设置密码,为AD用户创建邮箱等. 本文完全原创, ...

  10. MFC控件(8):command button与syslink control

    在VS 2008里MFC多了4种控件,分别是 split buttons ,command button , syslink controls和 network address controls. s ...