我已经将我的代码更新到Xcode 8.0 beta 6,但我陷入了关于新的非转义闭包默认值的困境。在下面的代码中,Xcode建议在完成之前添加@escaping
:
在下面代码的第一行中,但这仍然不会编译并循环。*
(编辑:事实上,@escaping应该在完成后添加:
,正如Xcode所建议的那样。警报可能仍会显示,但清理和编译会将其删除。* 如何重写/修复此代码才能在更新的 Swift 3 中工作?我已经查看了新手册,但我找不到正确的代码示例。
func doSomething(withParameter parameter: Int, completion: () -> ()) {
// Does something
callSomeOtherFunc(withCompletion: completion)
}
// Calling the method and execute closure
doSomething(withParameter: 2) {
// do things in closure
}
任何帮助非常感谢!
从xcode 8 beta 6 < code > @ no escape 是默认的。在此之前,< code>@escaping是默认设置。任何从以前版本升级到swift 3.0的人都可能会遇到这个错误。
不能在变量中存储@noescape
闭包。因为如果可以在变量中存储闭包,则可以从代码中的任何位置执行闭包。但@noescape
声明闭包参数不能转义函数的主体。
这将导致Xcode 8中的编译器错误
class MyClass {
var myClosure: (() -> ())?
func doSomething(finishBlock: () -> ()) {
myClosure = finishBlock // ‼️ Error: Assigning non-escaping parameter 'finishBlock' to an @escaping closure
}
}
这将编译正常(显式写入@escaping
)
class MyClass {
var myClosure: (() -> ())?
func doSomething(finishBlock: @escaping () -> ()) {
myClosure = finishBlock
}
}
@noescape
的好处:
有关详细信息,请查看:将非转义闭包设为默认值
在Swift 3之前,闭包属性< code>@autoclosure和< code>@noescape以前是闭包参数的属性,现在是参数类型的属性;请参见以下已被接受的Swift evolution提案:
您的具体问题与参数类型属性< code>@escaping(适用相同的新规则)有关,正如已被接受的Swift evolution提案中所述,默认情况下闭包参数是不可转义的:
这些建议现在都在Xcode 8的beta阶段实现(请参阅Xcode 8 beta 6的发行说明;开发人员。访问所需的帐户登录)
Xcode 8 beta 6中的新版本-Swift编译器:Swift语言
默认情况下,闭包参数是非转义的,而不是显式地使用@noscape
进行注释。使用@逃逸
指示闭包参数可以转义。@自动闭包(转义)
现在编写为@自动闭包@转义
。不建议使用注释@noscape
和@自动闭包(转义)
。(SE-0103)
...
Xcode 8测试版中的新功能–Swift和Apple LLVM编译器:Swift语言
@noescape
和@autoclosure
属性现在必须写在参数类型之前,而不是参数名称之前。〔SE-0049〕
因此,您使用非默认的@转义
属性,如下所示;应用于闭包参数的类型,而不是参数本身
func doSomething(withParameter parameter: Int, completion: @escaping () -> ()) {
// ...
}
(包括我在下面一个投票赞成的评论中对一个问题的回答,因为评论不是SO上的持久数据)
@Cristi Băluț259:“转义做什么?在swift3自动转换之前从未见过这个关键字…”
例如,请参阅上面SE-0103演进提案的链接(以及beta 6发行说明中引用的文本):以前,闭包参数默认情况下是转义的(因此不需要存在转义的显式注释),但现在默认情况下是不转义的。因此添加了@eving
来显式注释闭包参数可以转义(与其默认行为相反)。这也解释了为什么@noscape
现在已弃用(无需注释默认行为)。
为了解释闭包参数转义的含义,我引用了语言引用-属性:
我正在使用Equinox构建一个OSGi应用程序。对于这个应用程序来说,可以更新各个bundle是至关重要的。 应用程序检查HTTP服务器上的文件夹中是否有新版本的捆绑包,以及是否有任何新捆绑包可用。如果有新的包可用,应用程序将加载*. jar文件并更新此包。更新是通过停止捆绑包,用加载文件的输入流更新它,然后再次启动捆绑包来执行的。 问题是,在更新文件和重新启动应用程序后,文件的旧版本被使用,而
问题内容: 在学习Swift时,我正在编写一个简单的实践iOS应用程序,以从站点中抓取给定城市的天气信息,并将其显示在UILabel中。 该代码使用“ NSURLSession.sharedSession()。dataTaskWithURL”闭包。尽管我能够正确获取数据并在“ UILabel.text”中捕获相关文本,但是我无法获得实际的应用程序来显示更新的UILabel。 我究竟做错了什么?以下
Rust 的闭包实现与其它语言有些许不同。它们实际上是trait的语法糖。在这以前你会希望阅读trait章节,和trait对象。 都理解吗?很好。 理解闭包底层是如何工作的关键有点奇怪:使用()调用函数,像foo(),是一个可重载的运算符。到此,其它的一切都会明了。在Rust中,我们使用trait系统来重载运算符。调用函数也不例外。我们有三个trait来分别重载: # mod foo { pub
基本形式 闭包看起来像这样: let plus_one = |x: i32| x + 1; assert_eq!(2, plus_one(1)); 我们创建了一个绑定,plus_one,并把它赋予一个闭包。闭包的参数位于管道(|)之中,而闭包体是一个表达式,在这个例子中,x + 1。记住{}是一个表达式,所以我们也可以拥有包含多行的闭包: let plus_two = |x| { let
问题内容: 我正在尝试遵循Apple的“ 开始开发iOS应用程序(Swift)”教程,并且几乎完成了该教程。当我使用Xcode 8(我认为使用Swift 3而不是Swift 2)时,不得不修改本教程的几个部分。但是,我遇到了以下编译器错误,我不知道为什么: 在以下功能中: 我猜想有一个不同的NSIndexPath初始化程序在Swift 3中已更改,但我找不到它。难道我做错了什么? 谢谢, 问题答案
与其他包管理器(如)相比,我发现当更新与给定项目相关的包时,有一种奇怪的行为。 还根据留档,和选项 根据composer.json将依赖项升级到最新版本,并更新composer.lock文件。 事实上,正确地更新了新的包版本号。但是没有被修改,并且列出了旧的版本过低的包。 为什么会发生这种情况?是我做错了什么,还是这就是应该怎么做的?如果是这样的话,为什么两个文件中的一个是最新的,而另一个不是最新