我想在AnyObject中存储一个值,然后按如下方式检索它:
var obj:AnyObject = UIButton()
obj.setValue("James", forKey: "owner")
obj.valueForKey("owner")
但是,即使这些方法可用,AnyObject也不允许它,如错误所示:
setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key owner.'
怎么可以这样做?
答案 0 :(得分:5)
您无法分配UIButton的任意键。有些类确实允许这个(CALayer和CAAnimation出现,当然还有NSDictionary),但是UIButton和AnyObject都不是这样的类,也没有owner
属性 - 所以试图设置它是无稽之谈,是运行时崩溃的原因。您可以使用键设置按钮的现有属性,但不能像这样创建自己的密钥。
答案 1 :(得分:3)
您不能只动态地向对象添加属性。这不是斯威夫特的工作方式。你可以在Javascript(以及Obj-C中的一点)中使用它,但不能在Swift中使用它。
您的问题有几种简单的方法:
OwnedButton
。owner
属性。然后,您就可以设置button.owner = ...
。owner.addButton(button)
答案 2 :(得分:1)
关于按钮,您可以创建可以存储的对象数组。请参阅下面的NSCoding。
我定义对象的类 - 我写的游戏中的例子:
import Foundation
class ButtonStates: NSObject {
var sign: String = "+"
var level: Int = 1
var problems: Int = 10
var time: Int = 30
var skipWrongAnswers = true
func encodeWithCoder(aCoder: NSCoder!) {
aCoder.encodeObject(sign, forKey: "sign")
aCoder.encodeInteger(level, forKey: "level")
aCoder.encodeInteger(problems, forKey: "problems")
aCoder.encodeInteger(time, forKey: "time")
aCoder.encodeBool(skipWrongAnswers, forKey: "skipWrongAnswers")
}
init(coder aDecoder: NSCoder!) {
sign = aDecoder.decodeObjectForKey("sign") as String
level = aDecoder.decodeIntegerForKey("level")
problems = aDecoder.decodeIntegerForKey("problems")
time = aDecoder.decodeIntegerForKey("time")
skipWrongAnswers = aDecoder.decodeBoolForKey("skipWrongAnswers")
}
override init() {
}
}
我归档和检索这些对象的类:
import Foundation
class ArchiveButtonStates:NSObject {
var documentDirectories:NSArray = []
var documentDirectory:String = ""
var path:String = ""
func ArchiveButtons(#buttonStates: ButtonStates) {
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as String
path = documentDirectory.stringByAppendingPathComponent("buttonStates.archive")
if NSKeyedArchiver.archiveRootObject(buttonStates, toFile: path) {
//println("Success writing to file!")
} else {
println("Unable to write to file!")
}
}
func RetrieveButtons() -> NSObject {
var dataToRetrieve = ButtonStates()
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as String
path = documentDirectory.stringByAppendingPathComponent("buttonStates.archive")
if let dataToRetrieve2 = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? ButtonStates {
dataToRetrieve = dataToRetrieve2 as ButtonStates
}
return(dataToRetrieve)
}
}
从ViewController检索数据的示例:
let buttonStates = ArchiveButtonStates().RetrieveButtons() as ButtonStates
从ViewController存储数据的示例:
ArchiveGameData().ArchiveResults(dataSet: gameDataArray)
答案 3 :(得分:-2)
UIButton
,-[NSObject setValue:forKey:]
和-[NSObject valueForKey:]
是Objective-C Cocoa API。所以你的代码不能用于相应的Objective-C代码不起作用的完全相同的原因:
id obj = [[UIButton alloc] init];
[obj setValue:@"James" forKey:@"owner"];
[obj valueForKey:@"owner"];
一旦你明白了,你就会发现你的代码存在问题。