似乎Swift泛型可以正常工作,只要我不尝试以任何实际方式将它们组合在一起。我正在使用Swift 4.1,我想创建一个只包含弱引用的泛型数组。我可以将其定义为WeakList<T>
。到目前为止一切顺利。但是:我想使用T
的协议。斯威夫特说没有..
import Foundation
protocol Observer: class {
func stateChanged(sender: SomeClass, newState: Int)
}
struct WeakList<T> where T: AnyObject {
struct Ptr {
weak var p: T?
}
private var storage: [Ptr] = []
var aliveObjects: [T] {
var result: [T] = []
for ptr in storage {
if let p = ptr.p {
result.append(p)
}
}
return result
}
mutating func add(_ obj: T) {
storage.append(Ptr(p: obj))
}
// Let's ignore for a moment that this implementation leaks memory badly.
}
class SomeClass {
var someVar: WeakList<Observer> = WeakList<Observer>()
// Error: WeakList requires that 'Observer' be a class type
var thisIsOk: WeakList<NSObject> = WeakList<NSObject>()
}
(这不是我的原始代码,而是一个包含足够详细信息的最小可验证示例,因此没有人可以说“只是从结构中删除AnyObject约束”)
我想我想做的事情是不可能的。或者是吗?当我尝试使用Swift泛型做一些事情的时候,5次中的4次令人沮丧,我后来才知道我想做的事情是不可能的。 (顺便说一句,我可以轻松地在Objective-C中实现相同的功能。)
class
约束更改为AnyObject
约束=&gt;也不起作用。AnyObject
约束更改为class
约束=&gt;甚至没有编译。protocol Observer where Self: NSObject
并不会改变任何内容。 NSObject
是类类型,Observer
是NSObject
。应该遵循Observer
是类类型。 “是一种”关系在这里似乎不具有传递性。答案 0 :(得分:1)
使用当前实现,您无法从AnyObject
继承协议。您可以做的是为您的协议创建一个类型橡皮擦,然后使用它。现在,您的类型橡皮擦可以从AnyObject
继承。
这样的事情:
protocol Observer {
func stateChanged(sender: SomeClass, newState: Int)
}
class AnyObserver: NSObject, Observer {
private let observer: Observer
init(observer: Observer) {
self.observer = observer
}
func stateChanged(sender: SomeClass, newState: Int) {
observer.stateChanged(sender: sender, newState: newState)
}
}
struct WeakList<T> where T: AnyObject {
struct Ptr {
weak var p: T?
}
private var storage: [Ptr] = []
var aliveObjects: [T] {
var result: [T] = []
for ptr in storage {
if let p = ptr.p {
result.append(p)
}
}
return result
}
mutating func add(_ obj: T) {
storage.append(Ptr(p: obj))
}
// Let's ignore for a moment that this implementation leaks memory badly.
}
class SomeClass {
var someVar: WeakList<AnyObserver> = WeakList<AnyObserver>()
var thisIsOk: WeakList<NSObject> = WeakList<NSObject>()
}