4

我有一个通用结构声明如下:

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>因为该数组包含强引用。

Swift 中的纯类泛型约束是一个类似的问题,但并没有真正解决这个问题。

我们如何传递SomeProtocolto WeakReference

编辑: 以下场景编译得很好,但我们失去了保持弱引用的能力:

struct Reference<T> {
    var value: T?

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

var array: [Reference<SomeProtocol>] = []
4

3 回答 3

1

那很简单。你正在传递SomeProtocol这是一个protocol. 您需要在那里传递特定的类类型。

示例:

class SomeImplementation: SomeProtocol {
}

var weakSome: WeakReference<SomeImplementation> = ...

或者您可以通过使用注释标记协议来绕过它@objc,但我不喜欢这种方法。

@objc protocol SomeProtocol: class {

}

var weakSome: WeakReference<SomeProtocol> = ...

尝试检查此答案,它可能会为您提供有关该问题的更多背景信息。

于 2018-08-06T12:33:31.760 回答
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
}

在此处输入图像描述

于 2018-08-06T13:02:25.270 回答
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.

PS:在真正的 Xcode 项目中尝试此代码,因为在 Playground 中无法按预期工作。

于 2018-12-08T16:50:48.227 回答