Skip to content

Commit b1844f8

Browse files
committed
Fix weakified-task-chaining.
1 parent 63e0b33 commit b1844f8

File tree

1 file changed

+83
-72
lines changed

1 file changed

+83
-72
lines changed

SwiftTask/SwiftTask.swift

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ public class _Task<Error>
7070
{
7171
internal weak var _parentTask: _Task?
7272

73-
public init() {}
73+
internal let _weakified: Bool
74+
75+
public init(weakified: Bool) { self._weakified = weakified }
7476
public func pause() -> Bool { return true }
7577
public func resume() -> Bool { return true }
7678
public func cancel(error: Error? = nil) -> Bool { return true }
@@ -99,7 +101,6 @@ public class Task<Progress, Value, Error>: _Task<Error>
99101
internal var machine: Machine!
100102

101103
// store initial parameters for cloning task when using `try()`
102-
internal let _weakified: Bool
103104
internal var _initClosure: _InitClosure? // will be nil on fulfilled/rejected
104105

105106
/// progress value
@@ -138,15 +139,15 @@ public class Task<Progress, Value, Error>: _Task<Error>
138139
///
139140
public init(weakified: Bool, initClosure: InitClosure)
140141
{
141-
self._weakified = weakified
142-
self._initClosure = { machine, progress, fulfill, _reject, configure in
142+
super.init(weakified: weakified)
143+
144+
let _initClosure: _InitClosure = { machine, progress, fulfill, _reject, configure in
143145
// NOTE: don't expose rejectHandler with ErrorInfo (isCancelled) for public init
144146
initClosure(progress: progress, fulfill: fulfill, reject: { (error: Error?) in _reject(ErrorInfo(error: error, isCancelled: false)) }, configure: configure)
145147
return
146148
}
147149

148-
super.init()
149-
self.setup(weakified, self._initClosure!)
150+
self.setup(weakified, _initClosure)
150151
}
151152

152153
/// creates task without weakifying progress/fulfill/reject handlers
@@ -185,10 +186,7 @@ public class Task<Progress, Value, Error>: _Task<Error>
185186
/// NOTE: _initClosure has _RejectHandler as argument
186187
internal init(weakified: Bool = false, _initClosure: _InitClosure)
187188
{
188-
self._weakified = weakified
189-
self._initClosure = _initClosure
190-
191-
super.init()
189+
super.init(weakified: weakified)
192190
self.setup(weakified, _initClosure)
193191
}
194192

@@ -198,6 +196,8 @@ public class Task<Progress, Value, Error>: _Task<Error>
198196
// println("[init] \(self)")
199197
// #endif
200198

199+
self._initClosure = _initClosure
200+
201201
let configuration = Configuration()
202202

203203
weak var weakSelf = self
@@ -307,6 +307,8 @@ public class Task<Progress, Value, Error>: _Task<Error>
307307

308308
var task: _Task? = self
309309
while let parentTask = task?._parentTask {
310+
if parentTask._weakified { break }
311+
310312
parentTask.pause()
311313
task = parentTask
312314
}
@@ -317,6 +319,8 @@ public class Task<Progress, Value, Error>: _Task<Error>
317319

318320
var task: _Task? = self
319321
while let parentTask = task?._parentTask {
322+
if parentTask._weakified { break }
323+
320324
parentTask.resume()
321325
task = parentTask
322326
}
@@ -326,11 +330,12 @@ public class Task<Progress, Value, Error>: _Task<Error>
326330

327331
var task: _Task? = self
328332
while let parentTask = task?._parentTask {
333+
if parentTask._weakified { break }
334+
329335
parentTask.cancel()
330336
task = parentTask
331337
}
332338
}
333-
334339
}
335340

336341
deinit
@@ -354,15 +359,15 @@ public class Task<Progress, Value, Error>: _Task<Error>
354359

355360
if initClosure == nil { return self }
356361

357-
var nextTask: Task? = self
362+
var nextTask: Task = self
358363

359364
for i in 1...tryCount-1 {
360-
nextTask = nextTask!.failure { _ -> Task in
365+
nextTask = nextTask.failure { _ -> Task in
361366
return Task(weakified: weakified, _initClosure: initClosure!) // create a clone-task when rejected
362367
}
363368
}
364369

365-
return nextTask!
370+
return nextTask
366371
}
367372

368373
///
@@ -400,7 +405,7 @@ public class Task<Progress, Value, Error>: _Task<Error>
400405
///
401406
public func then<Progress2, Value2>(thenClosure: (Value?, ErrorInfo?) -> Task<Progress2, Value2, Error>) -> Task<Progress2, Value2, Error>
402407
{
403-
let newTask = Task<Progress2, Value2, Error> { machine, progress, fulfill, _reject, configure in
408+
let newTask = Task<Progress2, Value2, Error> { [weak self] machine, progress, fulfill, _reject, configure in
404409

405410
let bind = { [weak machine] (value: Value?, errorInfo: ErrorInfo?) -> Void in
406411
let innerTask = thenClosure(value, errorInfo)
@@ -443,27 +448,29 @@ public class Task<Progress, Value, Error>: _Task<Error>
443448
}
444449
}
445450

446-
switch self.machine.state {
447-
case .Fulfilled:
448-
bind(self.value!, nil)
449-
case .Rejected:
450-
bind(nil, self.errorInfo!)
451-
default:
452-
self.machine.addEventHandler(.Progress) { context in
453-
if let (_, progressValue) = context.userInfo as? Task<Progress2, Value2, Error>.ProgressTuple {
454-
progress(progressValue)
451+
if let self_ = self {
452+
switch self_.machine.state {
453+
case .Fulfilled:
454+
bind(self_.value!, nil)
455+
case .Rejected:
456+
bind(nil, self_.errorInfo!)
457+
default:
458+
self_.machine.addEventHandler(.Progress) { context in
459+
if let (_, progressValue) = context.userInfo as? Task<Progress2, Value2, Error>.ProgressTuple {
460+
progress(progressValue)
461+
}
455462
}
456-
}
457-
self.machine.addEventHandler(.Fulfill) { context in
458-
if let value = context.userInfo as? Value {
459-
bind(value, nil)
463+
self_.machine.addEventHandler(.Fulfill) { context in
464+
if let value = context.userInfo as? Value {
465+
bind(value, nil)
466+
}
460467
}
461-
}
462-
self.machine.addEventHandler(.Reject) { context in
463-
if let errorInfo = context.userInfo as? ErrorInfo {
464-
bind(nil, errorInfo)
468+
self_.machine.addEventHandler(.Reject) { context in
469+
if let errorInfo = context.userInfo as? ErrorInfo {
470+
bind(nil, errorInfo)
471+
}
465472
}
466-
}
473+
}
467474
}
468475

469476
}
@@ -492,7 +499,7 @@ public class Task<Progress, Value, Error>: _Task<Error>
492499
///
493500
public func success<Progress2, Value2>(successClosure: Value -> Task<Progress2, Value2, Error>) -> Task<Progress2, Value2, Error>
494501
{
495-
let newTask = Task<Progress2, Value2, Error> { machine, progress, fulfill, _reject, configure in
502+
let newTask = Task<Progress2, Value2, Error> { [weak self] machine, progress, fulfill, _reject, configure in
496503

497504
let bind = { [weak machine] (value: Value) -> Void in
498505
let innerTask = successClosure(value)
@@ -521,27 +528,29 @@ public class Task<Progress, Value, Error>: _Task<Error>
521528
}
522529
}
523530

524-
switch self.machine.state {
525-
case .Fulfilled:
526-
bind(self.value!)
527-
case .Rejected:
528-
_reject(self.errorInfo!)
529-
default:
530-
self.machine.addEventHandler(.Progress) { context in
531-
if let (_, progressValue) = context.userInfo as? Task<Progress2, Value2, Error>.ProgressTuple {
532-
progress(progressValue)
531+
if let self_ = self {
532+
switch self_.machine.state {
533+
case .Fulfilled:
534+
bind(self_.value!)
535+
case .Rejected:
536+
_reject(self_.errorInfo!)
537+
default:
538+
self_.machine.addEventHandler(.Progress) { context in
539+
if let (_, progressValue) = context.userInfo as? Task<Progress2, Value2, Error>.ProgressTuple {
540+
progress(progressValue)
541+
}
533542
}
534-
}
535-
self.machine.addEventHandler(.Fulfill) { context in
536-
if let value = context.userInfo as? Value {
537-
bind(value)
543+
self_.machine.addEventHandler(.Fulfill) { context in
544+
if let value = context.userInfo as? Value {
545+
bind(value)
546+
}
538547
}
539-
}
540-
self.machine.addEventHandler(.Reject) { context in
541-
if let errorInfo = context.userInfo as? ErrorInfo {
542-
_reject(errorInfo)
548+
self_.machine.addEventHandler(.Reject) { context in
549+
if let errorInfo = context.userInfo as? ErrorInfo {
550+
_reject(errorInfo)
551+
}
543552
}
544-
}
553+
}
545554
}
546555

547556
}
@@ -572,7 +581,7 @@ public class Task<Progress, Value, Error>: _Task<Error>
572581
///
573582
public func failure(failureClosure: ErrorInfo -> Task) -> Task
574583
{
575-
let newTask = Task { machine, progress, fulfill, _reject, configure in
584+
let newTask = Task { [weak self] machine, progress, fulfill, _reject, configure in
576585

577586
let bind = { [weak machine] (errorInfo: ErrorInfo) -> Void in
578587
let innerTask = failureClosure(errorInfo)
@@ -601,28 +610,30 @@ public class Task<Progress, Value, Error>: _Task<Error>
601610
}
602611
}
603612

604-
switch self.machine.state {
605-
case .Fulfilled:
606-
fulfill(self.value!)
607-
case .Rejected:
608-
let errorInfo = self.errorInfo!
609-
bind(errorInfo)
610-
default:
611-
self.machine.addEventHandler(.Progress) { context in
612-
if let (_, progressValue) = context.userInfo as? Task.ProgressTuple {
613-
progress(progressValue)
613+
if let self_ = self {
614+
switch self_.machine.state {
615+
case .Fulfilled:
616+
fulfill(self_.value!)
617+
case .Rejected:
618+
let errorInfo = self_.errorInfo!
619+
bind(errorInfo)
620+
default:
621+
self_.machine.addEventHandler(.Progress) { context in
622+
if let (_, progressValue) = context.userInfo as? Task.ProgressTuple {
623+
progress(progressValue)
624+
}
614625
}
615-
}
616-
self.machine.addEventHandler(.Fulfill) { context in
617-
if let value = context.userInfo as? Value {
618-
fulfill(value)
626+
self_.machine.addEventHandler(.Fulfill) { context in
627+
if let value = context.userInfo as? Value {
628+
fulfill(value)
629+
}
619630
}
620-
}
621-
self.machine.addEventHandler(.Reject) { context in
622-
if let errorInfo = context.userInfo as? ErrorInfo {
623-
bind(errorInfo)
631+
self_.machine.addEventHandler(.Reject) { context in
632+
if let errorInfo = context.userInfo as? ErrorInfo {
633+
bind(errorInfo)
634+
}
624635
}
625-
}
636+
}
626637
}
627638

628639
}

0 commit comments

Comments
 (0)