【问题标题】:Compile error in Swift 4 on parameter passingSwift 4 中的参数传递编译错误
【发布时间】:2017-07-19 07:39:01
【问题描述】:

我在 Xcode 9 Beta 3 中使用了 3rd party library。我在完成调用中收到以下错误,我无法解决此错误:

DispatchQueue.main.asyncAfter(deadline: .now() + delay) { 
    self.animationView?.alpha = 0
    self.containerView.alpha  = 1
    completion?()    // -> Error: Missing argument parameter #1 in call.   
}

并在完成函数中收到以下警告:

func openAnimation(_ completion: ((Void) -> Void)?) {    
    // -> Warning: When calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'?
}    

【问题讨论】:

    标签: swift ios11 xcode9-beta swift4


    【解决方案1】:

    在 Swift 4 中,对元组的处理比以往更加严格。

    这个闭包类型:(Void)->Void 表示一个闭包

    • 采用单个参数,其类型为Void
    • 返回Void,表示不返回值

    所以,尝试以下任何一种方法:

    Void 类型的值传递给闭包。 (空元组()Void 的唯一实例。)

    completion?(())
    

    否则:

    更改参数completion的类型。

    func openAnimation(_ completion: (() -> Void)?) {
        //...
    }
    

    请记住,即使在 Swift 3 中,(Void)->Void()->Void 两种类型也是不同的。因此,如果您打算表示 不带参数的闭包类型,则后者是合适的。

    这个变化是SE-0029 Remove implicit tuple splat behavior from function applications 的一部分,据说是在 Swift 3 中实现的,但似乎 Swift 3 还没有完全实现它。


    在这里,我向您展示一个简化的检查代码,您可以在 Playground 上检查差异。

    import Foundation
    
    //### Compiles in Swift 3, error and warning in Swift 4
    class MyClass3 {
    
        func openAnimation(_ completion: ((Void) -> Void)?) {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    
                completion?()
            }
        }
    
    }
    
    //### Compiles both in Swift 3 & 4
    class MyClass4 {
    
        func openAnimation(_ completion: (() -> Void)?) {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    
                completion?()
            }
        }
    
    }
    

    【讨论】:

    • 我将 ((Void) -> Void) 更改为 (() -> Void) 但在 完成时仍然出现错误? () 说它没有被打开。如果我解决了这个问题,它会将其更改为 (completion?)!() 但再次出现不同的错误。它进入一个循环,根本没有得到修复。
    • @yaali,(似乎我错过了添加我的最后一条评论......)我无法重现您在评论中描述的相同问题。我在我的答案中添加了一个检查代码,请检查并与您更新的代码进行比较。
    • 现在可以正常使用了。不知道为什么有时编译器会出错,有时运行时没有任何问题。
    • @yaali,我明白了。 Xcode 的这种奇怪行为经常(不幸的是,真的经常)让开发人员感到困惑。据我观察,Xcode 9 更渴望保持旧的(其中一些是在键入时生成的......)错误消息并且非常懒惰更新......希望它会在发布版本之前得到修复。
    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多