1

To avoid a memory leak when using NSBlockOperation in Objective-C, we would have to declare the variable as weak to be able to reference the block operation inside the block (to cancel if needed), typically like this:

__weak NSBlockOperation *blockOp  = [NSBlockOperation blockOperationWithBlock:^{
     if (blockOp.cancelled) {
         ...
     }
}];

But in Swift, when I try declare my NSBlockOpeartion as weak, it is always nil.

weak var blockOp = NSBlockOperation()

Without the weak reference, all is fine except it is leaking a little bit of memory each time. How can I reference the block inside the block without leaking memory in Swift?

Jeshua Lacock
  • 5,730
  • 1
  • 28
  • 58

1 Answers1

3

You can use an explicit capture list to capture an unowned reference to the operation. (This is one of the only times I'd actually suggest using unowned references, since the operation will be retained as long as its block is executing. If you're still uncomfortable with that guarantee, you could use weak instead.)

let op = NSBlockOperation()
op.addExecutionBlock { [unowned op] in
    print("hi")
    if op.cancelled { ... }
}

Note that this has to be split into two lines, because the variable can't be referenced from its own initial value.

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • That seems to work with first testing. I guess I would prefer weak, but like I mentioned in my post, when I declare it as weak I get nil when trying to allocate it with NSBlockOperation(), and like you say it has to be split in two lines, so I don't know how else to allocate it. – Jeshua Lacock Apr 20 '16 at 00:31
  • You can just use `[weak op]` the same way I've used `[unowned op]`. – jtbandes Apr 20 '16 at 00:32