斯威夫特:我怎样才能在完成体内调用我的函数?

Posted

技术标签:

【中文标题】斯威夫特:我怎样才能在完成体内调用我的函数?【英文标题】:Swift: How can I call my function inside completion body? 【发布时间】:2020-01-14 11:17:51 【问题描述】:

我有一个具有完成参数的预定义函数:

func checkNotificationEnabled(_ resultBlock : ((Bool)->())? = nil)
    Bool enabled = false

    ... a big block of code that gets enabled value 
    ...
    ... end block

    resultBlock?(enabled)

我需要获取真/假并将其传递给另一个函数:

@objc
func isNotificationEnabled(_
    resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock
) -> Void 
    checkNotificationEnabled  (enabled:Bool) in
        resolve(enabled)
    

得到错误:转义闭包捕获非转义参数'resolve'

如何将enabled 传递给resolve

【问题讨论】:

resolve参数添加@escapingfunc isNotificationEnabled(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void 啊,我试图发布一个答案,但已经有评论了 :) 无论如何,我的回答可能会帮助您了解“为什么”会发生这种情况。所以我会保持原样...... 【参考方案1】:

假设func isNotificationEnabled 上的RCTPromiseResolveBlock 是您尝试相对于func checkNotificationEnabledcompletion 执行的某个块,完成实际上“逃脱”(超出)函数的范围,并且编译器只是抱怨您的RCTPromiseResolveBlock 在完成回调期间可能不存在(正在执行中)

您必须将@escaping 标记为“解决”参数才能解决此问题。

当您了解什么是转义闭包时,您肯定会更清楚。看看这个问题:Escaping Closures in Swift

希望这会有所帮助。

【讨论】:

【参考方案2】: resolve 参数被传递给函数 checkNotificationEnabled 但未标记为 @escaping (Bool)->())? = nil optional 默认是nil,所以不需要赋值nil (Bool)->() 这等于更易读的版本Void
typealias ResultBlock = (Bool) -> Void
func checkNotificationEnabled(_ resultBlock: ResultBlock?) 
    var enabled = false

    ... a big block of code that gets enabled value 
    ...
    ... end block

    resultBlock?(enabled)


@objc
func isNotificationEnabled(_
    resolve: @escaping RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) 
    checkNotificationEnabled  enabled in
        resolve(enabled)
    

转义闭包

当闭包被传递为 函数的参数,但在函数返回后调用。 当您声明一个将闭包作为其之一的函数时 参数,你可以在参数类型前写@escaping 表示允许闭包逃逸。

闭包可以逃逸的一种方法是存储在变量中 这是在函数之外定义的。例如,许多功能 启动异步操作将闭包参数作为 完成处理程序。函数启动后返回 操作,但在操作完成之前不会调用闭包 完成——闭包需要逃逸,稍后调用。 source

【讨论】:

以上是关于斯威夫特:我怎样才能在完成体内调用我的函数?的主要内容,如果未能解决你的问题,请参考以下文章

斯威夫特:我怎样才能从代码中删除出口?

斯威夫特:我怎样才能让一个监听器报告连接何时丢失以及何时恢复?

内联函数详解

斯威夫特:我必须调用 Facebook 登录按钮两次才能获得 FBSDKAccessToken

我怎样才能在未来的某个特定时间运行一个函数? [关闭]

如何每小时调用一次函数?另外,我怎样才能循环这个?