Search code examples
iosswiftclosuresbreakpoints

Does a closure variable not retained if not used in inner scope in Swift?


I have a function like below:

func fetchComment(postId: String, index: Int, callback: @escaping (_ comment: Comment) -> Void) {
    rtDB!.fetchComment(postId: postId, callback: { comment in
        self.log.debug("postId: \(postId) - comment: \(comment)")
        self.fetchUsersForComments([postId: comment], callback: { usersList in
            // self.log.debug("++++  postId: \(postId) - comment: \(comment)")    // 1
            self.log.debug("postId: \(postId) - usersList: \(usersList)")
        })
    })
}

If I add a breakpoint at 1 with that line commented out, and print p comment, I get undefined identifier comment message. But comment is passed as the closure argument to fetchComment method. However if I uncomment the line marked 1 which uses the comment variable, and then print p comment with a breakpoint, it works fine. Why does the comment variable not defined if it is not being used in inner scope? Is it Swift compiler doing optimisation and removing the variable? I have no optimisation enabled for debug more.


Solution

  • The reason why you can't print comment when the line is uncommented is because you are currently in the scope of the closure, and closures by default don't capture anything. It's as if you are in another separate method.

    When you uncomment the line, you are now using the comment variable inside the closure. This means that the closure has to capture it. In the context of the "separate method" analogy, this is like the separate method takes an extra parameter called comment.

    Read more here