【问题标题】:value(forKey:) for NSObject not working in Swift 4NSObject 的 value(forKey:) 在 Swift 4 中不起作用
【发布时间】:2017-06-09 23:37:23
【问题描述】:

在 Xcode 9 Beta 中试用 Swift 4。

由于某种原因,我在 NSObject 上使用键值访问器时遇到了崩溃。

有什么想法吗?

import Cocoa

class Person: NSObject {
    var name = ""
    var age = 0
}

let alpha = Person()
alpha.name = "Robert"
alpha.age = 53

alpha.value(forKey: "name")
// error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

【问题讨论】:

  • 如果你用#keyPath(Person.name)而不是字符串调用value(forKey:),那么编译器将显示正确的错误消息并修复它!
  • 甚至,现在你在 Swift 4 中,使用 Swift 的键值编码机制print(alpha[keyPath: \Person.name]) :) 那么你不必从NSObject 继承,甚至可以使@987654327 @一个struct.
  • 我正在使用键值编码从字符串变量中动态选择要访问的属性。有没有办法使用新的 Swift 4 机制来做到这一点?
  • @closetCoder 您可以存储和传递关键路径,例如let name = \Person.name,但它们不是字符串(它们是强类型的)。字符串是表示键路径的弱类型,除非绝对必要,否则应该避免使用。您使用字符串键路径的用例是什么?

标签: swift swift4


【解决方案1】:

键值编码需要 Objective-C。在 Swift 4 中,您必须明确标记可从 Obj-C 访问的成员:

@objcMembers
class Person: NSObject {

class Person: NSObject {
    @objc var name = ""
    var age = 0
}

Swift Evolution 160

【讨论】:

    【解决方案2】:

    ObjC 推断在 Swift 4 中一直是 limited。您可以使用 objcMembers 标记您的类,以便编译器生成符合 ObjC 的访问器:

    @objcMembers
    class Person: NSObject {
        var name = ""
        var age = 0
    }
    

    或者通过在 Build Settings 中将 Swift 3 Objc Inference 设置为 On 来恢复旧行为:

    【讨论】:

    • 请注意,“Swift 3 @objc Inference”构建设置仅用于协助迁移,因此不是永久解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    相关资源
    最近更新 更多