onm*_*133 33 protocols reference hashtable weak swift
我正在使用Swift 2并使用WeakContainer作为存储一组弱对象的方式,就像 NSHashTable.weakObjectsHashTable()
struct WeakContainer<T: AnyObject> {
weak var value: T?
}
public protocol MyDelegate : AnyObject {
}
Run Code Online (Sandbox Code Playgroud)
然后在我的ViewController中,我声明
public var delegates = [WeakContainer<MyDelegate>]
Run Code Online (Sandbox Code Playgroud)
但这是错误的
使用MyDelegate作为符合协议AnyObject的具体类型不受支持
我看到的错误是,WeakContainer具有value声明为成员weak,因此T有望成为对象.但我也声明MyDelegate为AnyObject也.怎么解决这个问题?
The*_*heo 16
当我尝试实现弱容器时遇到了同样的问题.正如@plivesey在上面的评论中指出的那样,这似乎是Swift 2.2/Xcode 7.3中的一个错误,但预计会有效.
但是,某些Foundation协议不会出现此问题.例如,这编译:
let container = WeakContainer<NSCacheDelegate>()
Run Code Online (Sandbox Code Playgroud)
我发现这适用于标有该@objc属性的协议.您可以将其用作解决方法:
解决方法1
@objc
public protocol MyDelegate : AnyObject { }
let container = WeakContainer<MyDelegate>() // No compiler error
Run Code Online (Sandbox Code Playgroud)
由于这可能导致其他问题(某些类型无法在Objective-C中表示),这里有另一种方法:
解决方法2
AnyObject从容器中删除需求,并将值转换为AnyObject内部.
struct WeakContainer<T> {
private weak var _value:AnyObject?
var value: T? {
get {
return _value as? T
}
set {
_value = newValue as? AnyObject
}
}
}
protocol MyDelegate : AnyObject { }
var container = WeakContainer<MyDelegate>() // No compiler error
Run Code Online (Sandbox Code Playgroud)
警告:保存符合T但不符合的值AnyObject.
Vla*_*pko 12
我有同样的想法用泛型创建弱容器.
结果我创建了包装器NSHashTable并为您的编译器错误做了一些解决方法.
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?
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
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()
}
Run Code Online (Sandbox Code Playgroud)
它不是最好的解决方案,因为WeakSet可以使用任何类型进行初始化,如果此类型不符合AnyObject协议,则应用程序将崩溃.但我现在没有看到任何更好的解决方案.
你为什么要尝试使用泛型?我建议执行以下操作:
import Foundation
import UIKit
protocol MyDelegate : AnyObject {
}
class WeakContainer : AnyObject {
weak var value: MyDelegate?
}
class ViewController: UIViewController {
var delegates = [WeakContainer]()
}
Run Code Online (Sandbox Code Playgroud)
还有NSValue的nonretainedObject
| 归档时间: |
|
| 查看次数: |
8128 次 |
| 最近记录: |