Swift 3 :Closure use of non-escaping parameter may allow it to escape

后端 未结 3 721
梦如初夏
梦如初夏 2020-12-15 22:05

I have the following function where I have completion handler but I\'m getting this error:

Closure use of non-escaping parameter may allow it to escape
         


        
3条回答
  •  忘掉有多难
    2020-12-15 22:30

    @escaping is infectious to all calling methods, and the compiler determines when you must include it.

    Consider this example (which compiles):

    dispatchSometime( { print("Oh yeah") })
    
    func dispatchSometime(_ block: ()->()) {
        dispatchNow(block)
    }
    
    func dispatchNow(_ block: ()->()) {
        block()
    }
    

    This modified example, however, produces two errors of type non-escaping parameter may allow it to escape:

    dispatchSometime( { print("Oh yeah") })
    
    func dispatchSometime(_ block: ()->()) {
        dispatchLater(block)
    }
    
    func dispatchLater(_ block: ()->()) {
        DispatchQueue.main.async(execute: block)
    }
    

    The dispatch on main means the dispatchLater method needs @escaping, and once you've added that, the dispatchSometime method also requires @escaping for the example to compile.

    dispatchSometime( { print("Oh yeah") })
    
    func dispatchSometime(_ block: @escaping ()->()) {
        dispatchLater(block)
    }
    
    func dispatchLater(_ block: @escaping ()->()) {
        DispatchQueue.main.async(execute: block)
    }
    

    However, the take away is just:

    • Keep adding @escaping up the call chain until the compiler stops complaining.
    • The keyword doesn't change anything: it's a warning which says, essentially, "be careful to use weak with captured variables as they may be retained along with the block itself."

    Implications

    The really fun case with this is where you have to adjust several methods to include the @escaping keyword, which gets the compiler to stop complaining. However, if those methods are actually conforming to a protocol, that protocol's methods must also get the @escaping keyword, which also infects all other protocol conformants. Fun!

提交回复
热议问题