@@ -89,9 +89,11 @@ public class Task<Progress, Value, Error>: Printable
8989
9090 // store initial parameters for cloning task when using `try()`
9191 internal let _weakified : Bool
92- internal var _initClosure : _InitClosure ? // will be nil on fulfilled/rejected
92+ internal let _paused : Bool
93+ internal var _initClosure : _InitClosure ! // retained throughout task's lifetime
9394
94- /// wrapper closure for `_initClosure` to invoke only once when started `.Running`
95+ /// wrapper closure for `_initClosure` to invoke only once when started `.Running`,
96+ /// and will be set to `nil` afterward
9597 internal var _performInitClosure : ( Void -> Void ) ?
9698
9799 /// progress value
@@ -149,6 +151,7 @@ public class Task<Progress, Value, Error>: Printable
149151 public init ( weakified: Bool , paused: Bool , initClosure: InitClosure )
150152 {
151153 self . _weakified = weakified
154+ self . _paused = paused
152155
153156 let _initClosure : _InitClosure = { machine, progress, fulfill, _reject, configure in
154157 // NOTE: don't expose rejectHandler with ErrorInfo (isCancelled) for public init
@@ -219,16 +222,17 @@ public class Task<Progress, Value, Error>: Printable
219222 internal init ( weakified: Bool = false , paused: Bool = false , _initClosure: _InitClosure )
220223 {
221224 self . _weakified = weakified
225+ self . _paused = paused
222226
223227 self . setup ( weakified, paused: paused, _initClosure)
224228 }
225229
226230 internal func setup( weakified: Bool , paused: Bool , _initClosure: _InitClosure )
227- {
231+ {
228232// #if DEBUG
229- // println("[init] \(self)")
233+ // println("[init] \(self.name )")
230234// #endif
231-
235+
232236 let configuration = Configuration ( )
233237
234238 let initialState : TaskState = paused ? . Paused : . Running
@@ -277,12 +281,12 @@ public class Task<Progress, Value, Error>: Printable
277281
278282 // clear `_initClosure` & all StateMachine's handlers to prevent retain cycle
279283 $0. addEventHandler ( . Fulfill, order: 255 ) { context in
280- weakSelf? . _initClosure = nil
284+ // weakSelf?._initClosure = nil // comment-out: let `task.deinit()` handle this
281285 weakSelf? . _performInitClosure = nil
282286 weakSelf? . machine? . removeAllHandlers ( )
283287 }
284288 $0. addEventHandler ( . Reject, order: 255 ) { context in
285- weakSelf? . _initClosure = nil
289+ // weakSelf?._initClosure = nil
286290 weakSelf? . _performInitClosure = nil
287291 weakSelf? . machine? . removeAllHandlers ( )
288292 }
@@ -352,7 +356,7 @@ public class Task<Progress, Value, Error>: Printable
352356 deinit
353357 {
354358// #if DEBUG
355- // println("[deinit] \(self)")
359+ // println("[deinit] \(self.name )")
356360// #endif
357361
358362 // cancel in case machine is still running
@@ -366,55 +370,44 @@ public class Task<Progress, Value, Error>: Printable
366370 return self
367371 }
368372
369- /// Returns new task that is retryable for `tryCount-1` times.
370- /// `task.try(n)` is conceptually equal to `task.failure(clonedTask1).failure(clonedTask2)...` with n-1 failure-able.
373+ /// Creates cloned task.
374+ public func clone( ) -> Task
375+ {
376+ return Task ( weakified: self . _weakified, paused: self . _paused, _initClosure: self . _initClosure)
377+ }
378+
379+ /// Returns new task that is retryable for `maxTryCount-1` times.
371380 public func try( maxTryCount: Int ) -> Task
372381 {
373382 if maxTryCount < 2 { return self }
374383
375- let weakified = self . _weakified
376- let initClosure = self . _initClosure
377-
378- if initClosure == nil { return self }
379-
380- return Task { [ weak self] machine, progress, fulfill, _reject, configure in
381-
382- var chainedTasks = [ self !]
383- var nextTask : Task = self !
384-
385- for i in 1 ... maxTryCount- 1 {
386- nextTask = nextTask. progress { _, progressValue in
387- progress ( progressValue)
388- } . failure { _ -> Task in
389- return Task ( weakified: weakified, _initClosure: initClosure!) // create a clone-task when rejected
390- }
391-
392- chainedTasks += [ nextTask]
393- }
384+ return Task { machine, progress, fulfill, _reject, configure in
394385
395- nextTask . progress { _, progressValue in
386+ let task = self . progress { _, progressValue in
396387 progress ( progressValue)
388+ } . failure { [ weak self] _ -> Task in
389+ return self !. clone ( ) . try ( maxTryCount- 1 ) // clone & try recursively
390+ }
391+
392+ task. progress { _, progressValue in
393+ progress ( progressValue) // also receive progresses from clone-try-task
397394 } . success { value -> Void in
398395 fulfill ( value)
399396 } . failure { errorInfo -> Void in
400397 _reject ( errorInfo)
401398 }
402399
403400 configure. pause = {
404- for task in chainedTasks {
405- task. pause ( ) ;
406- }
401+ self . pause ( )
402+ task. pause ( )
407403 }
408404 configure. resume = {
409- for task in chainedTasks {
410- task. resume ( ) ;
411- }
405+ self . resume ( )
406+ task. resume ( )
412407 }
413408 configure. cancel = {
414- // NOTE: use `reverse()` to cancel from downstream to upstream
415- for task in chainedTasks. reverse ( ) {
416- task. cancel ( ) ;
417- }
409+ task. cancel ( ) // cancel downstream first
410+ self . cancel ( )
418411 }
419412
420413 } . name ( " \( self . name) -try( \( maxTryCount) ) " )
0 commit comments