Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve same behavior as with strongify in Swift?

I have a closure with a weak self, I need to ensure that self will be retained during execution of closure, and released by closure after execution is done. Previously it was done by @strongify. Is there any other ways to do so in Swift?

like image 527
Nikita Leonov Avatar asked Nov 15 '14 01:11

Nikita Leonov


3 Answers

While the other answers work, another option is to use backticks. Doing so does away with having to define strongSelf and allows using self without having to unwrap optional self.

let c: () -> Void = {
    [weak self] in
    guard let `self` = self else { 
        throw NSError(domain: "self was destroyed", code: 1, userInfo: nil) 
    }
    self.doSomethingNonOptionalSelf()  
}
like image 117
Ryan DeJesus Avatar answered Sep 30 '22 14:09

Ryan DeJesus


Use a local variable to establish a strong reference to self.

let c: () -> Void = {
        [weak self] in
        // assign unwrapped optional to another variable
        guard let strongSelf: TypeOfSelf = self  else {
            return // or throw an exception, up to you
        }
        strongSelf.doSomething()
}
like image 28
ylin0x81 Avatar answered Sep 30 '22 16:09

ylin0x81


Answering on an old question to raise an idiom I haven't seen a lot of people bring up: you can use withExtendedLifetime to guarantee that the weakened self won't disappear on you.

let c: () -> Void = {
        [weak self] in
        withExtendedLifetime(self) {
            self!.doSomething()
        }
}

Note that although withExtendedLifetime guarantees that the argument won't be destroyed before the invocation of its closure is complete, the argument is still an Optional, so you have to unwrap it.

References:

  1. Swift Standard Library Functions
  2. The Weak/Strong Dance in Swift
like image 31
Palpatim Avatar answered Sep 30 '22 16:09

Palpatim