DRAsyncOperations 1.0.1

DRAsyncOperations 1.0.1

测试已测试
Lang语言 Obj-CObjective C
许可协议 MIT
发布最后发布2016年1月

David Rodrigues 维护。



  • 作者:
  • David Rodrigues

实现了并发 NSOperation,以抽象并帮助创建异步操作。

动机

我们在异步的世界中编码。我们承诺。

-- PromiseKit

每个 iOS 开发人员肯定都会同意这个说法,我们代码的大部分都是高度异步的,这给我们带来了一些挑战。幸运的是,我们有一些机制来组织我们的业务逻辑,将 NSOperationNSOperationQueue 结合使用是其中之一,它功能强大且灵活。

然而,尽管具有很大的灵活性,如果您需要在 NSOperation 上进行异步调用,那就注定要失败了。记住,一个 NSOperation 将在 -main 方法返回后立即完成。所以,您可能会使用信号量或其他类似项来锁定操作,以便在异步调用运行期间将其锁住,否则它将在规定时间内完成。这感觉不太对劲。

实际上,您并不完全注定要失败,由于 NSOperation 提供的出色灵活性,您能够创建一个并发操作,在该操作中您可以完全控制何时将操作视为完成,并且只有当异步调用完成时才完成操作。

实现并发操作并不困难,但您需要对这种类型的每个操作进行一些特定的实现。这是 DRAsyncOperation 的主要原因,它是一个类,实现了使用并发操作所需的基本功能,从而可以在 NSOperation 中使用异步代码。

安装

手动

将位于 DRAsyncOperation 文件夹中的所有文件拖放到您的项目中,然后完成。您还可以将 Xcode 项目作为依赖项导入到您的工作区中。

用法

使用 DRAsyncOperation 实现异步操作非常简单,并且它可能看起来与实现自定义 NSOperation 非常相似。

  1. 继承 DRAsyncOperation 类;
  2. 覆盖方法 -asyncTask;(其中您实现异步代码),您可以将其视为非并发操作的自定义 -main 方法;
  3. 当您的异步代码执行完毕时,调用方法 -finish 来结束操作,这部分与 NSOperation 相比是新的。

上述方法在 DRAsyncOperationSubclass.h 中可用。

块 API

您也可以使用 DRAsyncBlockOperation 通过简单的块来创建异步操作,这可能看起来与 NSBlockOperation 非常相似。

手动启动操作

如果您创建了一个 DRAsyncOperation 的实例并调用 -start 来手动启动操作,您应该注意,由于这些操作是异步的,此调用可能不会在完成前阻塞。如果您想获得类似非并发操作的行为,应在 -start 之后调用 -waitUntilFinished

示例

Objective-C

1. 将异步任务封装在操作中

// DRNetworkAsyncOperation.h

#import "DRAsyncOperation.h"

@interface DRNetworkAsyncOperation : DRAsyncOperation

@end

// DRNetworkAsyncOperation.m

#import "DRNetworkAsyncOperation.h"
#import "DRAsyncOperationSubclass.h"

@implementation DRNetworkAsyncOperation

- (void)asyncTask
{
    NSURL *githubURL = [NSURL URLWithString:@"https://github.com"];

    [[NSURLSession sharedSession] dataTaskWithURL:githubURL
                                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        // Do your stuff ...

        // When you're done, finish the operation
        [self finish];
    }];
}

@end

2. 将异步任务封装在块中

NSOperationQueue *queue;

CLGeocoder *geocoder;
CLLocation *location;

NSOperation *asyncOperation = [DRAsyncBlockOperation asyncBlockOperationWithBlock:^(DRAsyncBlockOperationFinishBlock finish) {

    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

        // Do your stuff ...

        // When you're done, finish the operation
        finish();
    }];

}];

[queue addOperation:asyncOperation];

Swift

Swift 本身支持,您只需要在桥梁头文件中导入相关的头文件。

// If you want to implement async tasks in operations
#import "DRAsyncOperation.h"
#import "DRAsyncOperationSubclass.h"

// If you want to implement async tasks in blocks
#import "DRAsyncBlockOperation.h"

与 Objective-C 相比,Swift 中的块 API 更紧凑。

var queue: NSOperationQueue

var geocoder: CLGeocoder
var location: CLLocation

var asyncOperation: DRAsyncBlockOperation!

asyncOperation = DRAsyncBlockOperation { (finish) -> Void in

    // This is automatically checked for you at the beginning of the operation but you could check it during your execution
    if asyncOperation.isCancelled() {
        finish()
        return
    }

    geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in

        // Do your stuff ...

        // When you're done, finish the operation
        finish()

    })
}

queue.addOperation(asyncOperation)

创建者

David Rodrigues @dmcrodrigues

许可证

DRAsyncOperation 在 MIT 许可证下发布。