From 8ca1ceeca4f17b8dd771612c7cc46c2515b35827 Mon Sep 17 00:00:00 2001 From: James Ide Date: Wed, 26 Feb 2014 23:40:41 -0800 Subject: [PATCH] +[BFTask taskFromExecutor:withBlock] to easily create ad-hoc tasks This convenience class method makes it easier to create tasks from blocks without needing to write the code for a temporary `BFTask` or `BFTaskCompletionSource`. Usage: [[BFTask taskFromExecutor:executor withBlock:id ^{ return work_on_queue(); }] continueWithBlock:...]; As opposed to: BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; dispatch_async(queue, ^{ [tcs setResult:work_on_queue()]; }); [tcs.task continueWithBlock:...]; The convenience method also handles exceptions the same way the rest of BFTasks does so that's another plus. Test case is included. --- Bolts/BFTask.h | 13 +++++++++++++ Bolts/BFTask.m | 5 +++++ BoltsTests/TaskTests.m | 12 ++++++++++++ 3 files changed, 30 insertions(+) diff --git a/Bolts/BFTask.h b/Bolts/BFTask.h index bd98333fa..d602c68ab 100644 --- a/Bolts/BFTask.h +++ b/Bolts/BFTask.h @@ -58,6 +58,19 @@ typedef id(^BFContinuationBlock)(BFTask *task); */ + (instancetype)taskWithDelay:(int)millis; +/*! + Returns a task that will be completed after the given block completes with + the specified executor. + @param executor A BFExecutor responsible for determining how the + continuation block will be run. + @param block The block to immediately schedule to run with the given executor. + @returns A task that will be completed after block has run. + If block returns a BFTask, then the task returned from + this method will not be completed until that task is completed. + */ ++ (instancetype)taskFromExecutor:(BFExecutor *)executor + withBlock:(id (^)())block; + // Properties that will be set on the task once it is completed. /*! diff --git a/Bolts/BFTask.m b/Bolts/BFTask.m index be2e470bc..69d7f6774 100644 --- a/Bolts/BFTask.m +++ b/Bolts/BFTask.m @@ -140,6 +140,11 @@ + (BFTask *)taskWithDelay:(int)millis { return tcs.task; } ++ (BFTask *)taskFromExecutor:(BFExecutor *)executor + withBlock:(id (^)())block { + return [[self taskWithResult:nil] continueWithExecutor:executor withBlock:block]; +} + #pragma mark - Custom Setters/Getters - (id)result { diff --git a/BoltsTests/TaskTests.m b/BoltsTests/TaskTests.m index 7d45dbee7..15b0e9387 100644 --- a/BoltsTests/TaskTests.m +++ b/BoltsTests/TaskTests.m @@ -443,6 +443,18 @@ - (void)testWaitUntilFinished { XCTAssertEqualObjects(@"foo", task.result); } +- (void)testTaskFromExecutor { + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0L); + BFExecutor *queueExecutor = [BFExecutor executorWithDispatchQueue:queue]; + + BFTask *task = [BFTask taskFromExecutor:queueExecutor withBlock:^id() { + XCTAssertEqual(queue, dispatch_get_current_queue()); + return @"foo"; + }]; + [task waitUntilFinished]; + XCTAssertEqual(@"foo", task.result); +} + - (void)testExecuteImmediately { XCTAssertTrue([NSThread isMainThread]); BFTask *task = [BFTask taskWithResult:nil];