我使用Swift 2和WeakContainer来存储一组弱对象,就像NSHashTable.weakObjectsHashTable()

struct WeakContainer<T: AnyObject> {
    weak var value: T?
}

public protocol MyDelegate : AnyObject {

}

然后在我的ViewController中,我声明

public var delegates = [WeakContainer<MyDelegate>]

但这是错误的

不支持将MyDelegate用作符合协议AnyObject的具体类型

我看到错误是WeakContainervalue个成员声明为weak,所以T应该是object.但我也宣布MyDelegateAnyObject.怎么避开这个?

推荐答案

我也有同样的 idea ,用泛型创建弱容器

class WeakSet<ObjectType>: SequenceType {

    var count: Int {
        return weakStorage.count
    }

    private let weakStorage = NSHashTable.weakObjectsHashTable()

    func addObject(object: ObjectType) {
        guard object is AnyObject else { fatalError("Object (\(object)) should be subclass of AnyObject") }
        weakStorage.addObject(object as? AnyObject)
    }

    func removeObject(object: ObjectType) {
        guard object is AnyObject else { fatalError("Object (\(object)) should be subclass of AnyObject") }
        weakStorage.removeObject(object as? AnyObject)
    }

    func removeAllObjects() {
        weakStorage.removeAllObjects()
    }

    func containsObject(object: ObjectType) -> Bool {
        guard object is AnyObject else { fatalError("Object (\(object)) should be subclass of AnyObject") }
        return weakStorage.containsObject(object as? AnyObject)
    }

    func generate() -> AnyGenerator<ObjectType> {
        let enumerator = weakStorage.objectEnumerator()
        return anyGenerator {
            return enumerator.nextObject() as! ObjectType?
        }
    }
}

用法:

protocol MyDelegate : AnyObject {
    func doWork()
}

class MyClass: AnyObject, MyDelegate {
    fun doWork() {
        // Do delegated work.
    }
}

var delegates = WeakSet<MyDelegate>()
delegates.addObject(MyClass())

for delegate in delegates {
    delegate.doWork()
}

这不是最好的解决方案,因为WeakSet可以用任何类型初始化,如果这种类型不符合AnyObject协议,那么应用程序将崩溃.但我现在看不到更好的解决方案.

Swift相关问答推荐

通过SwiftUI中的列表 Select 从字典中检索值

SwiftUI:为什么@State在子视图中持续存在?

如何使用AsyncTimerSequence获取初始时钟,然后在指定的时间间隔内开始迭代?

Swift UI中视图上的值未更新

是否有一个带有空初始值设定项的 Swift 类/ struct 的标准协议

如何判断一个值是否为 Int 类型

有没有更快的方法来循环浏览 macOS 上已安装的应用程序?

如何确定扩展中的具体类型?

SwiftUI:从存储在 observableObject 中的数组中删除对象时查看崩溃

使用 Date.ParseStrategy 将字符串解析为日期

临时添加到视图层次 struct 后,Weak view引用不会被释放

Swift 2.0 方法不能标记为@objc,因为参数的类型不能在 Objective-C 中表示

在 Xcode 中自动实现 Swift 协议方法

在 iOS 中使用 Swift 保存 PDF 文件并显示它们

SwiftUI - 呈现工作表后导航栏按钮不可点击

两个 Date 对象之间的所有日期 (Swift)

在 Swift 中指定 UITextField 的边框半径

在 Swiftui 中是否有一种简单的方法可以通过捏合来放大图像?

TabView 在切换选项卡时重置导航堆栈

如何在swift中的每N个字符处为字符串添加分隔符?