2017-05-22 82 views
1

我有對象是這樣的:iOS Swift 3.1中的setValue和myObject.propertyName有什麼區別?

class Human: NSObject { 
    var name:String! 
    var age:Int! 
} 

而且使實例從對象是這樣的:

let instance = Human() 

並設置我的價值觀是這樣的:

instance.name = "Kirk" 
instance.age = 87 

,並打印這樣的:

print("name: \(instance.name)") // Kirk 
print("age: \(instance.age)") //87 

每件事情都可以。但現在把我的價值的另一種方式是這樣的:

instance.setValue("Kirk", forKey: "name") 
instance.setValue(87, forKey: "age") 

得到這個錯誤詮釋數據類型:

***終止應用程序由於未捕獲的異常 'NSUnknownKeyException',原因:「[setValue方法:forUndefinedKey:]:這個 類不是關鍵字值,它是關鍵時代的編碼標準。

爲什麼會發生這種情況?
以及如何解決這個問題,因爲我需要使用setValue()函數。

+1

區別在於'instance.name'通過本機Swift機制訪問屬性,而'instance.setValue(「Kirk」,forKey:「name」)'需要鍵值編碼KVC),它只有在類型可以在Objective-C中表示時纔有效。正如其他人指出的那樣,「Int!」不能用Objective-C表示,所以它不能參與KVC。將'age'從'Int!'更改爲'Int'或'NSNumber!',它會正常工作。 (顯然,如果將其更改爲'Int',則需要確保將其初始化爲非'nil'值,推測採用'init'方法將該值作爲參數。) – Rob

+0

可能重複[Why我可以不使用KVC從Objective-C對象到Swift屬性嗎?](http://stackoverflow.com/questions/35783888/why-can-i-not-use-kvc-from-an-objective-c- object-to-a-swift-property) –

回答

5

鍵值編碼(KVC)依賴於Objective-C功能,並且Int!類型在技術上是一種可選的值類型。可選的值類型不能在Objective-C中表示,這就是調用失敗的原因。

你可以看到編譯錯誤,如果你增加一個顯dynamic屬性:

class Human: NSObject { 
    var name:String! 
    dynamic var age: Int! 
} 

它將與Int工作。

無論如何,在這種情況下使用隱式unwrapped選項是一個壞主意。您應該將屬性設置爲非可選項,並在初始化程序中初始化它們。

+0

一些可選的值類型(如'String!')可以在Obj-C中表示 - 「Int」只是有問題,因爲它被橋接到「NSInteger」,因此沒有代表'nil'的方式。 – Hamish

+0

@Hamish確實,橋接對象是一個引用類型('Data',arrays,dictionaries等等))。 – Sulthan

2

Int!不能用其他提到的int Objective-C表示。這應該工作

class Human: NSObject { 
    var name:String! 
    var age : Int; 

    init(name:String?, age:Int) { 
     self.age = age 
     self.name = name 
    } 
} 
+0

由@Rob建議更新 – Bilal