EXC_BAD_ACCESS 使用 self.performSelector

EXC_BAD_ACCESS using self.performSelector

这是一个简单的学术而非真正的代码。

我想 运行 使用 performSelector 函数打印方法。但是如果我 运行 操场上的这段代码抛出异常:

EXC_BAD_ACCESS (code=EXC_I386_GPFLT).

代码:

//: Playground - noun: a place where people can play

import UIKit

@objc(Foo)
class Foo: NSObject {

    func timer() {
        self.performSelector( #selector(Foo.print))
    }

    @objc func print() {
        NSLog("print")
    }
}

let instance = Foo()
instance.timer()     // <-- EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

问题出在哪里?

尝试将您的 Foo.print() 更改为如下内容:

    @objc func print() -> AnyObject? {
        NSLog("print")
        return nil
    }

我相信代码也在 Playground 中运行。

performSelectors return类型不是Void.

- performSelector:

func performSelector(_ aSelector: Selector) -> Unmanaged<AnyObject>!

因此,Playground 尝试获取要显示的结果值。这实际上不是 returned.

这是一个不需要更改函数签名的解决方案:

class Foo {

    func timer() {
        (self as AnyObject).performSelector(#selector(Foo.print))
    }

    @objc func print() {
        NSLog("print")
    }
}

let instance = Foo()
instance.timer()

可能与 Objective-C API 桥接有关,仍在调查中...