我必須通過字符串名稱表示將值設置爲屬性。只能繼承從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後綴。我對嗎? –