我有一个通用结构声明如下:
struct WeakReference<T: AnyObject> {
weak var value: T?
init(value: T?) {
self.value = value
}
}
和协议:
protocol SomeProtocol: class {
}
但是我无法声明WeakReference<SomeProtocol>
类型的变量,编译器抱怨
“ WeakReference”要求
SomeProtocol
为类类型
有趣的是,在Swift中,class
是AnyObject的类型别名。
我实际上想保存一个WeakReference<SomeProtocol>
数组,因为该数组包含强引用。
Class-only generic constraints in Swift是一个类似的问题,但并不能真正解决这个问题。
我们如何将SomeProtocol
传递给WeakReference
?
编辑: 以下情况可以很好地编译,但是我们失去了保持弱引用的能力:
struct Reference<T> {
var value: T?
init(value: T?) {
self.value = value
}
}
var array: [Reference<SomeProtocol>] = []
答案 0 :(得分:1)
您如何看待这种方法?
class WeakReference<T> {
weak var value: AnyObject?
init(value: T?) {
self.value = value as? AnyObject
}
}
protocol SomeProtocol: class {
}
class A: SomeProtocol { }
let araayOfSomeProtocolObjects: [SomeProtocol] = (0...5).map {_ in A() }
let arrayOfWeakReferences: [WeakReference<SomeProtocol>] = araayOfSomeProtocolObjects.map { WeakReference(value: $0) }
for item in arrayOfWeakReferences {
print(item.value is A) // true
}
答案 1 :(得分:0)
那很简单。您正在传递SomeProtocol
的{{1}}。您需要传递特定的类类型。
示例:
protocol
或者您可以通过使用class SomeImplementation: SomeProtocol {
}
var weakSome: WeakReference<SomeImplementation> = ...
批注标记协议来绕过它,但是我不喜欢这种方法。
@objc
尝试检查this answer,它可能会为您提供有关此问题的更多背景信息。
答案 2 :(得分:0)
我认为这应该可以解决您的问题。
struct WeakReference<T> {
private weak var privateRef: AnyObject?
var ref: T? {
get { return privateRef as? T }
set { privateRef = newValue as AnyObject }
}
init(_ ref: T? = nil) {
self.ref = ref
}
}
// usage
protocol MyProto: class { }
extension UIViewController: MyProto { }
let vc = UIViewController()
var weakRef = WeakReference<MyProto>(vc)
print(weakRef.ref)
您显然可以将WeakReference
与非类协议或非桥接值类型一起使用。
如果尝试这样做,您将始终得到nil
。
P.S。 :请在实际的Xcode项目上尝试此代码,因为在Playground中无法按预期工作。