虽然NSOperation
和NSOperationQueue
对于一些重复性问题表现良好,而NSInvocation
对于其他问题也表现良好,但iOS并没有包括一套易于管理大量任意背景任务的工具。EDQueue通过使用GCD和SQLite3提供了一个高级接口,用于实现线程化的作业队列。您只需处理提供的代理方法中的作业,EDQueue会处理其余部分。
开始使用EDQueue的最简单方法是查看附带的示例应用程序。XCode项目文件可以在项目 > queue.xcodeproj
中找到。
EDQueue需要libsqlite3.0.dylib
和FMDB(存储引擎)。像往常一样,处理所有这些细节最快的方法是使用CocoaPods。EDQueue作为单例实现,以便在整个应用程序中创建作业。但是,所有任务都通过单个代理方法进行处理,因此通常最合理的方法是将EDQueue设置为应用程序代理。
YourAppDelegate.h
#import "EDQueue.h"
@interface YourAppDelegate : UIResponder <UIApplicationDelegate, EDQueueDelegate>
YourAppDelegate.m
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[EDQueue sharedInstance] setDelegate:self];
[[EDQueue sharedInstance] start];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
[[EDQueue sharedInstance] stop];
}
- (EDQueueResult)queue:(EDQueue *)queue processJob:(NSDictionary *)job
{
sleep(1); // This won't block the main thread. Yay!
// Wrap your job processing in a try-catch. Always use protection!
@try {
if ([[job objectForKey:@"task"] isEqualToString:@"success"]) {
return EDQueueResultSuccess;
} else if ([[job objectForKey:@"task"] isEqualToString:@"fail"]) {
return EDQueueResultFail;
}
}
@catch (NSException *exception) {
return EDQueueResultCritical;
}
return EDQueueResultCritical;
}
SomewhereElse.m
[[EDQueue sharedInstance] enqueueWithData:@{ @"foo" : @"bar" } forTask:@"nyancat"];
为了使事情保持简单,委托方法期望有EDQueueResult
类型的返回值,允许三种不同的状态:
EDQueueResultSuccess
:用于指示作业成功完成EDQueueResultFail
:用于指示作业失败,应该重试(直到指定的retryLimit
)EDQueueResultCritical
:用于指示作业严重失败,不应再次尝试从v0.6.0版本开始,队列包含一个适合处理HTTP请求或磁盘I/O等异步作业的委托方法。
- (void)queue:(EDQueue *)queue processJob:(NSDictionary *)job completion:(void (^)(EDQueueResult))block
{
sleep(1);
@try {
if ([[job objectForKey:@"task"] isEqualToString:@"success"]) {
block(EDQueueResultSuccess);
} else if ([[job objectForKey:@"task"] isEqualToString:@"fail"]) {
block(EDQueueResultFail);
} else {
block(EDQueueResultCritical);
}
}
@catch (NSException *exception) {
block(EDQueueResultCritical);
}
}
从v0.7.0版本开始,队列包含一组方法,有助于每个任务特定的队列内省。
- (Boolean)jobExistsForTask:(NSString *)task;
- (Boolean)jobIsActiveForTask:(NSString *)task;
- (NSDictionary *)nextJobForTask:(NSString *)task;
- (void)enqueueWithData:(id)data forTask:(NSString *)task;
- (void)start;
- (void)stop;
- (void)empty;
- (Boolean)jobExistsForTask:(NSString *)task;
- (Boolean)jobIsActiveForTask:(NSString *)task;
- (NSDictionary *)nextJobForTask:(NSString *)task;
- (EDQueueResult)queue:(EDQueue *)queue processJob:(NSDictionary *)job;
- (void)queue:(EDQueue *)queue processJob:(NSDictionary *)job completion:(void (^)(EDQueueResult result))block;
EDQueueResultSuccess
EDQueueResultFail
EDQueueResultCritical
@property (weak) id<EDQueueDelegate> delegate;
@property (readonly) Boolean isRunning;
@property (readonly) Boolean isActive;
@property NSUInteger retryLimit;
EDQueueDidStart
EDQueueDidStop
EDQueueDidDrain
EDQueueJobDidSucceed
EDQueueJobDidFail
EDQueue是为iOS 5及以上版本设计的。
EDQueue使用ARC构建。如果您在的项目中没有使用自动引用计数(Automatic Reference Counting, ARC),您需要将所有EDQueue源文件的编译器标志设置为-fobjc-arc
。在Xcode中这样做,请转到您的活动目标并选择“构建阶段”选项卡。现在选择所有EDQueue源文件,按Enter键,输入-fobjc-arc
然后点击“完成”以为EDQueue启用ARC。