参数传递时Swift 4中的编译错误

参数传递时Swift 4中的编译错误,swift,ios11,xcode9-beta,swift4,Swift,Ios11,Xcode9 Beta,Swift4,我在Xcode 9 Beta 3中使用过。我在完成调用中遇到以下错误,我无法解决此错误: DispatchQueue.main.asyncAfter(deadline: .now() + delay) { self.animationView?.alpha = 0 self.containerView.alpha = 1 completion?() // -> Error: Missing argument parameter #1 in call.

我在Xcode 9 Beta 3中使用过。我在完成调用中遇到以下错误,我无法解决此错误:

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 4中,元组的处理比以往更加严格

此闭包类型:
(Void)->Void
表示

  • 接受单个参数,其类型为
    Void
  • 返回
    Void
    ,表示不返回值
因此,请尝试以下任一方法:

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

否则:

更改参数的类型
completion

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

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

这一变化是据说在Swift 3中实施的一部分,但似乎Swift 3尚未完全实施


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

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),但仍然在完成时出错?()说它没有打开。如果我解决了这个问题,它会将其更改为(完成?)!()但再次出现不同的错误。它是一个循环,一点也不固定。@yaali,(似乎我错过了添加我最后的评论…)我无法重现您在评论中描述的相同问题。我已经在我的答案中添加了一个检查代码,请检查并将其与您的更新代码进行比较。它现在工作正常。不知道为什么有时编译器会出错,有时运行时不会出现任何问题。@yaali,我明白了。这种奇怪的Xcode行为经常(不幸的是,实际上经常)使开发人员感到困惑。据我观察,Xcode 9更希望保留旧的错误消息(其中一些是在键入时生成的…),并且非常懒于更新。。。希望它将被修复,直到发布版本。
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?()
        }
    }

}