将AnyObject转换为T

时间:2014-08-09 11:05:43

标签: swift

代码:

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中实现相同的正确方法是什么。

1 个答案:

答案 0 :(得分:4)

问题是NSNumber不是Bool。它看起来像Bool,可以转换为Bool,但它实际上是一种不同的类型。您的anyObject实际上是NSNumber,并要求as? T T BoolNSNumber太远了。这仍然可能是一个编译器错误,因为它应该与泛型相同,但它是问题发生的地方。

您需要将通用功能专门化为get { return Bool(get("BoolProperty", defaultValue: NSNumber(bool: false))) }

AnyObject

它仍然值得打开雷​​达。无论是否使用通用,它都不应该有不同的行为。

尽管如此,部分问题在于使用BoolAnyObject不是Any。它是AnyObject。当您尝试将其分配给NSNumber时,它会转换为let a:AnyObject = false。我不知道有关这方面的任何文件;我在游乐场里凭经验练习出来。比较let a:Any = falsevar anyObject: Any? = getValue(key) 的结果。

理论上,这应该解决所有问题:

{{1}}

但它目前崩溃了编译器。