在开发过程中,我们经常会遇到一下耗时的操作,比如说文件的上传、下载、压缩、解压缩等过程,开发过蓝牙的小伙伴都知道蓝牙的操作也是一个耗时的操作,尤其是那些以蓝牙为工具的项目,比如说蓝牙在智能家居中的使用,这些都是耗时的操作。有时候我们需要对这些耗时的操作精准的加以控制,这时候大多数人都会想到用多线程来处理,那么怎样才能用相对简单的代码来实现对这些耗时操作的控制呢?
在OC中有很多方法都能实现,这里我只说我经常用的NSOperation和NSOperationQueue相结合的方法
这里是通过NSOperation的子类,通过相关代码来控制它的状态(如果对NSOperation的四种状态不了解的童鞋可以自行补脑,这里就不多说了)来实现,下面是声明文件内容:
#import "HJBlockOperation.h"
#import <Foundation/Foundation.h>
@class HJBlockOperation;
typedef void (^continueBlock)(HJBlockOperation *con);
@interface HJBlockOperation : NSOperation
//仿NSOperation的四种状态 写出自己可以控制的对应的状态属性(ready状态暂时用不到,就不写了,其实最主要的就一个:isFinished,只有这个状态变成YES,才证明这个操作完成了)
@property(nonatomic ,assign , getter = isFinished)BOOL hjFinished;
@property(nonatomic ,assign , getter = isExecuting)BOOL hjExecuting;
@property(nonatomic ,assign , getter = isConcurrent)BOOL hjConcurrent;
@property(nonatomic, copy) continueBlock myBlock;
- (void)continueWithBlock:(continueBlock)blk;
@end
实现方法也是很简单,只需要这写代码
#import "HJBlockOperation.h"
@implementation HJBlockOperation
-(void)main
{
@autoreleasepool {
if (self.isCancelled) {
return;
}
_hjConcurrent =YES;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.myBlock(self);
}];
}
}
-(void)continueWithBlock:(continueBlock)blk
{
if (blk) {
self.myBlock = blk;
}
}
- (void)setHjFinished:(BOOL)hjFinished
{
[self willChangeValueForKey:@"isFinished"];
_hjFinished = hjFinished;
[self didChangeValueForKey:@"isFinished"];
}
- (void)setHjExecuting:(BOOL)hjExecuting
{
[self willChangeValueForKey:@"isExecuting"];
_hjExecuting = hjExecuting;
[self didChangeValueForKey:@"isExecuting"];
}
- (void)setHjConcurrent:(BOOL)hjConcurrent
{
_hjConcurrent = hjConcurrent;
}
@end
调用时候是这样的:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
NSMutableArray *operaArray = [NSMutableArray array];
for (int index = 0; index < 1; index ++) {
HJBlockOperation *blo = [[HJBlockOperation alloc] init];
[blo continueWithBlock:^(HJBlockOperation *con) {
NSLog(@"第%d条任务开始",index + 1);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"第%d条任务结束",index + 1);
//等任务结束后调用这句代码,就标明此操作已结束
blo.hjFinished = YES;
});
}];
[operaArray addObject:blo];
}
HJBlockOperation *operation = [[HJBlockOperation alloc] init];
[operation continueWithBlock:^(HJBlockOperation *con) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://ppt.downhot.com/d/file/p/2014/08/16/0b999aee4d45bc266637043b7cf04654.jpg"]];
NSLog(@"开始下载图片");
if (data) {
operation.hjFinished = YES;
NSLog(@"下载完了");
dispatch_async(dispatch_get_main_queue(), ^{
_imageView.image = [UIImage imageWithData:data];
});
}
}];
[operaArray addObject:operation];
[queue addOperations:operaArray waitUntilFinished:NO];
源代码:https://github.com/HJZone/HJBlockOperation