32

With closures I usually append [weak self] onto my capture list and then do a null check on self:

func myInstanceMethod()
{
    let myClosure =
    {
       [weak self] (result : Bool) in
       if let this = self
       { 
           this.anotherInstanceMethod()
       }
    }   

    functionExpectingClosure(myClosure)
}

How do I perform the null check on self if I'm using a nested function in lieu of a closure (or is the check even necessary...or is it even good practice to use a nested function like this) i.e.

func myInstanceMethod()
{
    func nestedFunction(result : Bool)
    {
        anotherInstanceMethod()
    }

    functionExpectingClosure(nestedFunction)
}
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Jaja Harris
  • 4,266
  • 4
  • 23
  • 22
  • Learning from the rintaro's answer I wrote a more robust answer [here](https://stackoverflow.com/a/41984023/5175709) – mfaani Sep 23 '19 at 13:47

2 Answers2

38

Unfortunately, only Closures have "Capture List" feature like [weak self]. For nested functions, You have to use normal weak or unowned variables.

func myInstanceMethod() {
    weak var _self = self
    func nestedFunction(result : Bool) {
        _self?.anotherInstanceMethod()
    }

    functionExpectingClosure(nestedFunction)
}
Jaja Harris
  • 4,266
  • 4
  • 23
  • 22
rintaro
  • 51,423
  • 14
  • 131
  • 139
-4

Does not seem to be the case anymore. This is valid in swift 4.1:

class Foo {
    var increment = 0
    func bar() {
        func method1() {
            DispatchQueue.main.async(execute: {
                method2()
            })
        }

        func method2() {
            otherMethod()
            increment += 1
        }
        method1()
    }

    func otherMethod() {

    }
}

The question remains: How is self captured ?

dcow
  • 7,765
  • 3
  • 45
  • 65
MLefrancois
  • 768
  • 5
  • 12
  • If by "valid" you mean that `self` is not strongly captured then I can't approve that. In my case I had a closure and I was calling a nested `func` from within this closure and the class would not be released, i.e. `deinit` was not called. At least that's what my research/debugging showed me. – mathz Jun 21 '18 at 15:19
  • it will be capture strongly here – adamz Sep 12 '18 at 07:12