swift - 如何在 perform(selector, withObject) 中将闭包作为参数传递

标签 swift

我正在尝试将闭包作为参数传递给 swift 并在选择器方法中执行它。

override func viewDidLoad() {
    super.viewDidLoad()

    let closure = {
        print(self.isCityChoosen)
    }
    perform(#selector(foo(param:)), with: closure)
}

@objc func foo(param: () -> () ) {
    param()
}

但是我有

线程 1:EXC_BAD_ACCESS(代码=1,地址=0x0) 执行 param() 时运行时出错 为什么会出现这个错误? 有解决办法吗?

最佳答案

您的闭包不是 Objective-C block ,因此无法通过 ObjC 运行时传递。您必须使用 @convention 将其标记为一个 block 。

let closure: @convention(block) () -> Void = { ... }

您可以通过分配将现有闭包转换为 block :

let closure = { ... }
let block: @convention(block) () -> Void = closure
perform(#selector(foo(param:)), with: block)

Objective-C block 实际上是对象,并且参与 ARC。发生崩溃是因为 perform 试图在非 block 上调用 Block_copy

当然,通常选择器不是 Swift 中的正确工具,您应该首先将任何基于选择器的接口(interface)转换为只接受函数参数。如果您发现自己在使用 perform,那么您可能在 Swift 中走错了路。但如果您需要,它仍然可用。

关于swift - 如何在 perform(selector, withObject) 中将闭包作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55340270/

相关文章:

ios - 无法调用非函数类型的值 : UITableView

ios - 如何让 startScene 上的按钮转到 GameScene

ios - 如何过渡出父级 UINavigationController

ios - 为什么在呈现 View Controller 后 UIView 从层次结构中删除?

ios - 无法将类型 '[AnyObject]' 的值转换为预期的参数类型 '[MKAnnotation]' 错误

ios - swift : Disable FrontViewController when Rear is Displayed

swift - 避免在 DispatchQueue 中使用 self

Android LayoutInflation 的 iOS/Swift 等价物

未执行 Swift dataTaskWithRequest 完成 block

swift - 值(forKey :) for NSObject not working in Swift 4