代码:
class User
{
class var BoolProperty: Bool
{
get {
var anyObject: AnyObject? = getValue("BoolProperty")
if let value = anyObject as? Bool {
return value
}
else {
return false
}
}
set(value) {
setValue("BoolProperty", value: value)
}
}
private class func getValue(key: String) -> AnyObject?
{
var store = NSUserDefaults.standardUserDefaults();
return store.objectForKey(key) as AnyObject?
}
}
通过测试:
class UserTests: XCTestCase
{
func testFields()
{
User.BoolProperty = true
var result = User.BoolProperty
XCTAssertEqual(true, result)
}
}
但是下面的代码没有通过相同的测试,它使用T而不是Bool进行投射:
class User
{
class var BoolProperty: Bool
{
get {
return get("BoolProperty", defaultValue: false)
}
set(value) {
setValue("BoolProperty", value: value)
}
}
private class func getValue(key: String) -> AnyObject?
{
var store = NSUserDefaults.standardUserDefaults();
return store.objectForKey(key) as AnyObject?
}
private class func get<T>(key: String, defaultValue: T) -> T
{
var anyObject: AnyObject? = getValue(key)
if let value = anyObject as? T {
return value
}
else {
return defaultValue
}
}
}
看来,由于某种原因,if let value = anyObject as? T
在转换为T时总是返回false。
在C#中,这是使用无类型集合的典型示例,我想知道在Swift中实现相同的正确方法是什么。
答案 0 :(得分:4)
问题是NSNumber
不是Bool
。它看起来像Bool
,可以转换为Bool
,但它实际上是一种不同的类型。您的anyObject
实际上是NSNumber
,并要求as? T
T
Bool
为NSNumber
太远了。这仍然可能是一个编译器错误,因为它应该与泛型相同,但它是问题发生的地方。
您需要将通用功能专门化为get {
return Bool(get("BoolProperty", defaultValue: NSNumber(bool: false)))
}
:
AnyObject
它仍然值得打开雷达。无论是否使用通用,它都不应该有不同的行为。
尽管如此,部分问题在于使用Bool
。 AnyObject
不是Any
。它是AnyObject
。当您尝试将其分配给NSNumber
时,它会转换为let a:AnyObject = false
。我不知道有关这方面的任何文件;我在游乐场里凭经验练习出来。比较let a:Any = false
和var anyObject: Any? = getValue(key)
的结果。
理论上,这应该解决所有问题:
{{1}}
但它目前崩溃了编译器。