将typealias存储为NSHashTable中的类类型

时间:2019-01-28 13:42:48

标签: ios swift

让我们假设我有一个协议,只有类可以确认,并使用我创建的typealias并结合了某些类类型。

protocol Foo: class {}
typealias FooView = UIView & Foo

我想将符合此协议的UIView实例存储在弱哈希表中。所以我这样做:

let hashtable = NSHashTable<FooView>.weakObjects()

但是我收到以下错误:

  

“ NSHashTable”要求“ FooView”(又名“ Foo&UIView”)为类类型

我知道NSHashTable仅适用于引用类型,但我没有得到,因为UIView是引用类型,而Foo协议也是类类型,恕我直言,它应该是有效的声明。

我了解,我可以创建一个如下所示的类:

class FooView: UIView, Foo {}

但是,这可能行不通。其他人还有其他想法如何使用typealias并将其存储在HashTable中吗?

2 个答案:

答案 0 :(得分:1)

(简化的)NSHashTable的定义如下:

class NSHashTable<ObjectType> : NSObject where ObjectType : AnyObject

并且Foo组件不符合AnyObject的要求(请参阅Protocol doesn't conform to itself?),以了解协议为何不符合其他协议的更多详细信息。

对此限制的一种解决方案是使用包装器类:

class FooViewWrapper {
    let view: FooView

    init(view: FooView) {
        self.view = view
    }
}

let hashtable = NSHashTable<FooViewWrapper>.weakObjects()

或通过泛型:

class Ref<T>{
    let value: T

    init(_ value: T) {
        self.value = value
    }
}

let hashtable = NSHashTable<Ref<FooView>>.weakObjects()

包装和解开此类视图会添加一些额外的代码,但可以很好地与哈希表配合使用。

答案 1 :(得分:-3)

您可以尝试创建符合Foo协议的UIView类的扩展:

protocol Foo {
    var bar: Int { get }
}

extension UIView: Foo {
    var bar = 4
}

如果确实需要类型别名,则还可以在UIView类本身上创建一个类型别名。