4

I want to understant self in Swift closure. For Ex -

() -> Void = { [weak self] in
    guard let `self` = self else { 
        self.callMethod2()
    }
    self.callMethod3()
}

Why we use backtick here? Is it good programming practice? How self is weakly captured here?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
srus2017
  • 394
  • 2
  • 14
  • 3
    See https://stackoverflow.com/questions/41503740/swift-variable-name-with-backtick – rmaddy May 01 '18 at 15:46
  • 2
    Note that [soon you'll be allowed to say](https://github.com/apple/swift/pull/15306) `guard let self = self else {...}` without the backticks – the parser will treat `self` as an ordinary identifier in that context, allowing it to be rebound :) – Hamish May 01 '18 at 16:22
  • 4
    Further discussion on the matter: https://forums.swift.org/t/the-future-of-weak-self-rebinding/10846 – Hamish May 01 '18 at 16:23

2 Answers2

7

Swift 4.2 recently adopted a proposal to add this to the language:

guard let self = self else { return }

The proposed solution entails allowing self to be upgraded from a weak reference to a strong reference using optional binding.

For more details refer swift evolution proposal SE-0079

Learner
  • 1,107
  • 12
  • 14
5

self is a reserved word in Swift. Since you're creating a new local var called self you need to mark it with back-ticks, as explained in the link from rmaddy.

Note that the usual convention for mapping weak self to a strong var is to use the name strongSelf:

() -> Void = { [weak self] in
    guard let strongSelf = self else { 
        //your code to call self.callMethod2() can't succeed inside the guard (since in that case weak self is nil)
        //self.callMethod2()
        return   //You must have a statement like return, break, fatalEror, or continue that breaks the flow of control if the guard statement fails
    }
    strongSelf.callMethod3()
}
Hamish
  • 78,605
  • 19
  • 187
  • 280
Duncan C
  • 128,072
  • 22
  • 173
  • 272