我必须通过字符串名称表示将值设置为属性。只能继承从NSObject继承的类@objc
import Foundation
@objc class A:NSObject {
var x:String = ""
}
var a = A()
a.x = "ddd"
print(a.x)
a.setValue("zzz", forKey:"x")
print(a.x)
和编译过程中遇到奇怪的错误:
main.swift:4:2: error: only classes that inherit from NSObject can be declared @objc
@objc class A:NSObject {
~^~~~~
main.swift:13:1: error: value of type 'A' has no member 'setValue'
a.setValue("zzz", forKey:"x")
^ ~~~~~~~~
有谁知道发生了什么事?
PS:再现的上夫特4.0 & 3.1.1(Ubuntu的16.04.3 LTS)
被修改:
import Foundation
@objc class A:NSObject {
@objc dynamic var x:String = ""
}
var a = A()
a.x = "ddd"
print(a.x)
a.setValue("zzz", forKeyPath:"x")
print(a.x)
输出:
错误:只从NSObject的继承可以是类声明@objc @objc class A:NSObject {
错误:属性无法标记@objc,因为它的类型不能在Objective-C表示 @objc动态无功X:字符串= “”
注:迅捷结构不能在Objective-C来表示 @objc动态无功X:字符串= “”
错误:的值'A' 型有没有成员 '的setValue' a.setValue( “ZZZ”,forKeyPath: “X”)
编辑2: 只是想如 “C风格”:
func set<T>(_ val:T, forKey key:String) {
print("SET:\(self) \(key) to \(val)")
let ivar: Ivar = class_getInstanceVariable(type(of: self), key)!
let pointerToInstanceField:UnsafeMutableRawPointer = Unmanaged.passRetained(self).toOpaque().advanced(by: ivar_getOffset(ivar))
let pointer = pointerToInstanceField.assumingMemoryBound(to: T.self)
pointer.pointee = val
}
它运作良好,但在递归调用中导致访问不良。可能有些保留/释放问题。将挖杓。也没有在Linux上(如在答案中提到)
[如何在Objective-C中使用Swift非NSObject子类]的可能重复(https://stackoverflow.com/questions/32997550/how-to-use-swift-non-nsobject-subclass-in-objective -c) – jww
这是一个误导性的错误(你可能想要提交一个错误)。问题很简单,在Linux上没有使用Swift的Obj-C运行时。你不能标记'@ objc',并且你不能使用KVC(改为使用Swift键路径)。 – Hamish
@Hamish,谢谢你的建议。你能指点我一些关于Swift关键路径的文档吗?不能谷歌任何关于。它也需要(at)objc后缀。我对吗? –