在斯威夫特?,swift"/>

首页 > 解决方案 > 什么相当于 Obj.C 的 NSMutableDictionary在斯威夫特?

问题描述

Swift中的 Obj.C 等价物是什么NSMutableDictionary<Class, Class>

我试过了:

var dictionary = [AnyClass: AnyClass]()

但是,这会引发错误:Type 'AnyClass' (aka 'AnyObject.Type') does not conform to protocol 'Hashable'

由于每个名称只能有一个类,我们知道给定的类引用指的是一个唯一的类;在给定的命名空间中只有一个“字符串”。那么为什么这不是可散列的呢?

我也试过:

var dictionary = NSMutableDictionary<AnyClass, AnyClass>

然而,这也失败了:Cannot specialize non-generic type 'NSMutableDictionary'

我认为 Swift 应该是类型安全的,但这里编译器鼓励我将任何内容放入此 NSMutableDictionary 中,而不对其进行类型检查以确保它是 AnyClass!

另外,不要跟我说“你一开始就不应该这样做”,因为我没有这样做,在一些需要我翻译成 Swift 的 Objective C 代码中已经是这样了。我只是想以最好的方式做到这一点——如果这意味着我必须求助于非类型安全的 NSMutableDictionary,那就这样吧,但这似乎很荒谬。

当然,我在这里遗漏了一些东西……我遗漏了什么?

标签: swift

解决方案


我发现,你可以在 Swift 中获得的最接近的方法是这样做:

var classToClassMapping = Dictionary<ObjectIdentifier, AnyClass>()

extension Dictionary where Key == ObjectIdentifier, Value == AnyClass {
    subscript<T>(keyType: T.Type) -> AnyClass? {
        get {
            let id = ObjectIdentifier(keyType)
            return self[id]
        }
        set {
            let id = ObjectIdentifier(keyType)
            self[id] = newValue
        }
    }
}

classToClassMapping[Yay.self] = NSString.self

if let stringClass = classToClassMapping[Yay.self] as? NSString.Type {

    print(stringClass.init(string: "hell yeah"))

}

// Prints "hell yeah"


// Alternative:

switch classToClassMapping[Yay.self] {
case let val as NSString.Type:
    print(val.init(string: "yaiirrr boy"))
default:
    print("woops")
}

// prints "yaiirrr boy"

非常适合我的需要!(这里使用 Swift 5.1)


推荐阅读