XAsync 2.0.1

XAsync 2.0.1

测试已测试
语言语言 Obj-CObjective C
许可 MIT
发布最后发布2016年6月

Pavlo Gorb维护。



XAsync 2.0.1

  • 作者:
  • Pavlo Gorb

介绍

处理异步操作可能会很繁琐。一般来说,有两种方法来进行这些操作:使用代码块和GCD(NSOperations也在此),以及使用代理。当代码执行很多这样的异步操作时,在某个点上代码会变得很难阅读。显然,同步代码更容易阅读和维护。这就是XAsync发挥作用的地方。它允许调用异步操作,并在异步操作完成之前暂停当前方法的进一步执行。它以非阻塞的方式实现,因此在异步操作执行时,调用者线程可以处理其他事件。

XAsync功能灵感来自于C#的await代码结构。

安装

为Objective-C/Swift应用程序安装XAsync最容易且推荐的方式是使用CocoaPods进行安装和维护。

  • 首先,您需要将CocoaPods安装到您的计算机上。可以在终端中执行以下行来完成此操作:
$ sudo gem install cocoapods

CocoaPods是用Ruby构建的,因此可以使用OS X上可用的默认Ruby进行安装。

  • 打开Xcode并创建一个新的项目(在Xcode菜单中:文件->新建->项目),或者使用以下方法导航到现有的Xcode项目:
$ cd <Path to Xcode project folder>
  • 在Xcode项目的文件夹中创建一个新的文件,将其命名为“Podfile”(使用大写的“P”且不带任何扩展名)。以下示例显示了如何为一款OSX应用程序编写Podfile。如果您计划使用其他平台,过程将非常相似。您只需要将平台更改为您对应的值。您可以在这里找到有关平台值的更多信息。
source 'https://github.com/CocoaPods/Specs.git'
platform :osx, '10.10'
use_frameworks!

target '<Put your Xcode target name here>' do
    pod 'XAsync', '~>2.0'
end
  • 回到您的终端窗口并执行以下行
$ pod install
  • 关闭Xcode项目(如果它仍然打开)。为了任何进一步的开发目的,您应该使用CocoaPods为您创建的.xcworkspace文件。

您应该已经准备好一切。如果您在CocoaPods安装过程中遇到任何问题,请尝试在cocoapods.org中查找更多信息。

Swift备注

尽管XAsync以Objective-C作为其主要语言,但在Swift应用程序中仍然可以很容易地使用它。在按照安装部分所述安装XAsync后,需要执行以下操作

  • 在Swift项目中创建一个新头文件。
  • 可以将其命名为如BridgingHeader.h
  • 在这里放入以下行
@import XAsync;
  • 在Xcode构建设置中找到名为Objective-C桥接头的设置,并将路径设置为BridgingHeader.h文件的路径。请注意,此路径是以Xcode项目文件夹为相对路径。

有关在同一个项目中使用Objective-C和Swift的更多信息,请参阅此处

使用方法

下面提供了在同步模式下使用XAsync功能的示例。

等待单个任务的完成

等待单个任务,没有任何结果

Objective-C
//...
@import XAsync;
//...
XAsyncTask *t1 = [XAsyncTask taskWithAction:^(XAsyncTask * __weak _Nonnull task) {
    NSLog(@"Task 1 has been started.");
    for (NSInteger i = 0; i < 1000000000; i++) {
    }
    NSLog(@"Task 1 is about to end.");
}];
NSLog(@"About to start async task 1.");
[t1 await];
NSLog(@"Async task 1 has been done.");
//...
Swift
//...
let t1 = XAsyncTask { (task) in
    print("Task 1 has been started.")
    for _ in 0..<1000000000 {
    }
    print("Task 1 is about to end.")
}
print("Task 1 is about to start.")
t1.await()
print("Task 1 has been done.")
//...

等待单个任务的完成并获取结果

下面的例子展示了等待单个任务完成的示例,该任务期望返回一些结果

Objective-C
///...
XAsyncTask *t2 = [XAsyncTask taskWithAction:^(XAsyncTask * __weak _Nonnull task) {
        NSLog(@"Task 2 has been started.");
        NSInteger i = 0;
        for (i = 0; i < 1000000000; i++) {
        }
        NSLog(@"Task 2 is about to end.");
        task.result = [NSNumber numberWithInteger:i];
}];
NSLog(@"About to start async task 2.");
[t2 await];
NSLog(@"Async task 2 has been done with result: %@", [(NSNumber *)t2.result stringValue]);
///...
Swift
///...
let t2 = XAsyncTask { (task) in
    print("Task 2 has been started.")
    var i = 0
    for _ in 0..<1000000000 {
        i += 1;
    }
    print("Task 2 is about to end.")
    task?.result = i;
}
print("Task 2 is about to start.")
t2.await()
print("Task 2 has been done with result: \(t2.result)")
///...

等待一串任务的完成

下面的例子展示了如何等待给定序列中的所有任务完成。任务将按照它们在初始序列中的顺序开始和完成。

Objective-C
///...
XAsyncTask *one_s = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Sequence task 1 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Sequence task 1 is about to end.");
}];
XAsyncTask *two_s = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Sequence task 2 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Sequence task 2 is about to end.");
}];
XAsyncTask *three_s = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Sequence task 3 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Sequence task 3 is about to end.");
}];
NSLog(@"About to start sequence.");
[XAsyncTask awaitSequence:@[ one_s, two_s, three_s ]];
NSLog(@"Sequence has been finished.");
///...
Swift
///...
let one_s = XAsyncTask { (task) in
    print("Sequence task 1 has been started.")
    for _ in 0..<100000000 {
    }
    print("Sequence task 1 is about to end.")
}
let two_s = XAsyncTask { (task) in
    print("Sequence task 2 has been started.")
    for _ in 0..<100000000 {
    }
    print("Sequence task 2 is about to end.")
}
let three_s = XAsyncTask { (task) in
    print("Sequence task 3 has been started.")
    for _ in 0..<100000000 {
    }
    print("Sequence task 3 is about to end.")
}
print("About to start sequence.")
XAsyncTask.awaitSequence([one_s, two_s, three_s])
print("Sequence has been finished.")
///...

等待集合中所有任务的完成

在一些情况下,只需要完成一定数量的任务,执行或完成顺序并不重要。重要的是所有任务都已经完成。在这种情况下,以下示例可能是有用的。

Objective-C
///...
XAsyncTask *one_all = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Pool task 1 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Pool task 1 is about to end.");
}];
XAsyncTask *two_all = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Pool task 2 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Pool task 2 is about to end.");
}];
XAsyncTask *three_all = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Pool task 3 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Pool task 3 is about to end.");
}];
NSSet *poolAll = [NSSet setWithObjects:one_all, two_all, three_all, nil];
NSLog(@"About to start pool of tasks.");
[XAsyncTask awaitAll:poolAll];
NSLog(@"All tasks have been finished.");
///...
Swift
///...
let one_all = XAsyncTask { (task) in
    print("Pool task 1 has been started.")
    for _ in 0..<100000000 {
    }
    print("Pool task 1 is about to end.")
}
let two_all = XAsyncTask { (task) in
    print("Pool task 2 has been started.")
    for _ in 0..<100000000 {
    }
    print("Pool task 2 is about to end.")
}
let three_all = XAsyncTask { (task) in
    print("Pool task 3 has been started.")
    for _ in 0..<100000000 {
    }
    print("Pool task 3 is about to end.")
}
print("About to start all tasks' pool.")
XAsyncTask.awaitAll(Set(arrayLiteral: one_all, two_all, three_all))
print("All tasks have been finished.")
///...

等待集合中任何任务的完成

在某些情况下,等待特定组中的至少一个任务完成可能很重要。以下示例说明。

Objective-C
///...
XAsyncTask *one_any = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Pool task 1 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Pool task 1 is about to end.");
}];
XAsyncTask *two_any = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Pool task 2 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Pool task 2 is about to end.");
}];
XAsyncTask *three_any = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nullable task) {
    NSLog(@"Pool task 3 has been started.");
    for (NSInteger i = 0; i < 100000000; i++) {
    }
    NSLog(@"Pool task 3 is about to end.");
}];
NSSet *poolAny = [NSSet setWithObjects:one_any, two_any, three_any, nil];
NSLog(@"About to start a pool.");
[XAsyncTask awaitAny:poolAny];
NSLog(@"Waiting has been finished.");
///...
Swift
///...
let one_any = XAsyncTask { (task) in
    print("Pool task 1 has been started.")
    for _ in 0..<100000000 {
    }
    print("Pool task 1 is about to end.")
}
let two_any = XAsyncTask { (task) in
    print("Pool task 2 has been started.")
    for _ in 0..<100000000 {
    }
    print("Pool task 2 is about to end.")
}
let three_any = XAsyncTask { (task) in
    print("Pool task 3 has been started.")
    for _ in 0..<100000000 {
    }
    print("Pool task 3 is about to end.")
}
print("About to start a pool.")
XAsyncTask.awaitAny(Set(arrayLiteral: one_all, two_all, three_all))
print("Waiting has been finished.")
///...

等待特定任务触发的信号

如果一个需要完成的任务本身就是异步的,并且依赖于某些其他条件(例如,从服务获取响应),那么答案是:使用以下示例中所示的awaitSignal方法。

Objective-C
///...
XAsyncTask *ts = [XAsyncTask taskWithAction:^(XAsyncTask *__weak  _Nonnull task) {
    NSLog(@"Signal task has been started.");
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        NSInteger i = 0;
        for (i = 0; i < 1000000000; i++) {
        }
        task.result = [NSNumber numberWithInteger:i];
        [task fireSignal];
    });
    NSLog(@"Signal task is about to end.");
}];
NSLog(@"About to start signal task.");
[ts awaitSignal];
NSLog(@"Signal task has been done: %@", [(NSNumber *)ts.result stringValue]);
///...
Swift
///...
let ts = XAsyncTask { (task) in
    print("Signal task has been started.");
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)) {
        var i = 0;
        for _ in 0..<1000000000 {
            i += 1
        }
        task?.result = i
        task?.fireSignal()
    }
    print("Signal task is about to end.")
}
print("About to start signal task.")
ts.awaitSignal()
print("Signal task has been done: \(ts.result)")

///...

许可

使用遵循MIT 许可协议。有关详细信息,请参阅LICENSE文件。