首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将闭包更新为Swift 3-@转义

将闭包更新为Swift 3-@转义
EN

Stack Overflow用户
提问于 2016-08-21 11:06:28
回答 2查看 51.7K关注 0票数 75

我已经将我的代码更新为Xcode 8.0beta 6,但我仍然坚持使用新的非转义闭包默认值。在下面的代码中,Xcode建议在下面代码的第一行中在completion:前面添加completion:,但这仍然不会编译,而且会循环进行。*

(编辑:实际上,正如Xcode所建议的那样,@转义应该在 completion:之后添加到中。警报可能仍然显示,但清理和编译将删除它。)*如何重新编写/修复此代码以在更新的Swift 3中工作?我看了一下新手册,但找不到合适的代码样本。

代码语言:javascript
复制
func doSomething(withParameter parameter: Int, completion: () -> ()) {
    // Does something

    callSomeOtherFunc(withCompletion: completion)
  }

// Calling the method and execute closure 
doSomething(withParameter: 2) {
  // do things in closure
}

任何帮助都非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-21 12:05:17

Swift 3:闭包参数属性现在应用于参数类型,而不是参数本身。

在Swift 3之前,闭包属性@autoclosure@noescape过去是闭包参数的属性,但现在是参数类型的属性;请参阅以下已接受的Swift演化建议:

您的具体问题涉及参数类型属性@escaping (同样的新规则适用于该属性),正如已接受的Swift演进建议中所描述的那样,默认情况下闭包参数是不可转义的:

这些建议现在都是在Xcode 8的beta阶段实现的(参见Xcode 8 beta 6的发行说明;dev )。访问所需的帐户登录)

Xcode 8 beta 6中的新版本- Swift编译器: Swift语言 默认情况下,闭包参数是不转义的,而不是显式地使用@noescape进行注释。使用@escaping指示闭包参数可能转义。@autoclosure(escaping)现在被写成@autoclosure @escaping。不建议使用注释@noescape@autoclosure(escaping)。(SE-0103) ..。 Xcode 8测试版中的新版本- Swift和Apple编译器: Swift语言 现在必须在参数类型之前而不是在参数名称之前写入@noescape@autoclosure属性。SE-0049

因此,您使用非默认的@escaping属性,如下所示;应用于闭包参数的类型,而不是参数本身。

代码语言:javascript
复制
func doSomething(withParameter parameter: Int, completion: @escaping () -> ()) {
    // ...
}

(将我对一个问题的回答包括在下面的评论中,因为评论不是关于SO的持久数据)

@Cristi Băluță:“转义是干什么的?在ă自动转换之前从未见过这个关键字.”

参见指向SE-0103进化建议的链接(以及beta 6发行说明中引用的文本):以前,闭包参数默认情况下是转义(因此不需要为转义提供显式注释),但现在默认情况下不进行转义。因此,添加了@escaping来显式注释闭包参数可能会转义(与其默认行为相反)。这也解释了为什么现在不推荐@noescape (不需要对默认行为进行注释)。

为了解释闭包参数正在转义意味着什么,我引用语言参考-属性

“将此属性应用于方法或函数声明中的参数类型,以指示参数的值可以存储以供以后执行。这意味着该值可以超过调用的生存期。”

票数 58
EN

Stack Overflow用户

发布于 2016-10-24 10:28:18

@noescape

从xcode 8到beta 6,@noescape是默认的。在此之前,@escaping是默认的。任何人从以前的版本更新到Swive3.0可能都会遇到这个错误。

不能在变量中存储@noescape闭包。因为如果可以在变量中存储闭包,则可以在代码中的任何地方执行闭包。但是@noescape指出闭包参数不能转义函数的主体。

这将导致Xcode 8中的编译器错误。

代码语言:javascript
复制
class MyClass {

    var myClosure: (() -> ())?

    func doSomething(finishBlock: () -> ()) {
        myClosure = finishBlock    // ‼️ Error: Assigning non-escaping parameter 'finishBlock' to an @escaping closure
    }
}

这将编译ok (显式写入@escaping)

代码语言:javascript
复制
class MyClass {

    var myClosure: (() -> ())?

    func doSomething(finishBlock: @escaping () -> ()) {
        myClosure = finishBlock
    }
}

@noescape**:**的效益

  • 编译器可以优化代码以获得更好的性能。
  • 编译器可以负责内存管理。
  • 没有必要在闭包中使用对self的弱引用

详情请参阅:使非转义闭包成为默认设置。

票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39063499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档