There is a way to introduce retain cycle and get a BFTask object leaked. Just create a task that is never finished with result/error or cancelled. Here is the example:
[[self asyncTask] continueWithSuccessBlock:^id _Nullable(BFTask * _Nonnull t) {
...
}];
- (BFTask *)syncTask {
BFTaskCompletionSource *taskSource = [BFTaskCompletionSource taskCompletionSource];
return taskSource.task;
}
The BFTask object is captured in the executionBlock block of the continueWithExecutor:block:cancellationToken: method.

I'd propose to get rid of self reference capturing and cancel the task on deallocation (if needed).