代码之家  ›  专栏  ›  技术社区  ›  christopher.online

类型A要求类型B为Swift 4类

  •  10
  • christopher.online  · 技术社区  · 6 年前

    下面的代码给出了一个编译错误

    “weakreference”要求“serviceDelegate”是类类型

    protocol ServiceDelegate: AnyObject {
        func doIt()
    }
    
    class SomeClass() {
        // compile error occurs in this line
        private var observers = [WeakReference<ServiceDelegate>]()
    }
    

    参考代码:

    final class WeakReference<T: AnyObject> {
    
        private(set) weak var value: T?
    
        init(value: T?) {
            self.value = value
        }
    }
    

    如何修复此错误?应根据此正确声明委托 site .

    到目前为止我所做的尝试:

    • 从更改委托协议一致性 AnyObject class 不能解决问题。
    • 在干净的操场上尝试上述代码。
    4 回复  |  直到 6 年前
        1
  •  6
  •   dan    6 年前

    你不能有 WeakReference<ServiceDelegate> . ServiceDelegate 它本身不是 AnyObject ,它只要求符合它的任何东西都是 任何对象 .

    你需要 SomeClass 泛型,并将泛型类型用作 WeakReference :

    class SomeClass<T: ServiceDelegate> {
        private var observers = [WeakReference<T>]()
    }
    

    如果通用打开 某个班级 太过狭隘,您希望能够将多个不相关类的实例作为观察器,然后我将通过在 Weakreference公司 :

    final class WeakServiceDelegate {
        private(set) weak var value: ServiceDelegate?
    
        init(value: ServiceDelegate?) {
            self.value = value
        }
    }
    
    class SomeClass {
        private var observers = [WeakServiceDelegate]()
    }
    

    或者你可以做 Weakreference公司 有条件地符合 服务委托 :

    extension WeakReference: ServiceDelegate where T: ServiceDelegate {
        func doIt() {
            value?.doIt()
        }
    }
    

    然后使用一个数组 服务委托 在里面 某个班级 :

    class SomeClass {
        private var observers = [ServiceDelegate]()
    
        func addObserver<T: ServiceDelegate>(_ observer: T) {
            observers.append(WeakReference(value: observer))
        }
    }
    
        2
  •  4
  •   OOPer    6 年前

    如你所见, ServiceDelegate 是协议,不是类类型。 即使所有类型都符合 服务委托 是类类型, 服务委托 本身不是类类型。这是目前纯swift协议的事实。

    尝试 @obc ,Objective-C协议有点不同:

    @objc protocol ServiceDelegate {
        func doIt()
    }
    

    您可能希望排除objective-c类,并使一些纯swift类符合 服务委托 但是我找不到其他的方法。

        3
  •  3
  •   Vyacheslav    6 年前

    问题是 WeakReference<ServiceDelegate> 线路错误

    private var observers = [WeakReference<ServiceDelegate>]()

    您必须使用一个具体的类,而不是内部的协议 <>

    您有两种可能的解决方案:

    1. 创建一个具体类并使用它:
    class ServiceClass: ServiceDelegate {
    //...
    }
    private var observers = [WeakReference<ServiceClass>]()
    
    1. 或者使用协议。我的意思是:

       final class WeakReference<T: AnyObject> {
      
           private(set) weak var value: T?
      
           init(value: T?) {
               self.value = value
           }
       }
      
       protocol SomeContainer: AnyObject { }
       extension WeakReference: SomeContainer { }
      

    用这种方式:

     private var observers = [SomeContainer]()
    

    注释

    使用这种方式:

    class SomeClass<T: ServiceDelegate> {
        private var observers = [WeakReference<T>]()
    }
    

    您只需将问题转移到代码的另一部分。

        4
  •  0
  •   Максим Колесник    6 年前

    创建纯协议

    public protocol AnyWeakValue {
        var anyValue: Any? { get }
    }
    

    从继承AssociatedType协议 Anyweakalue公司

    public protocol WeakValue: AnyWeakValue {
        associatedtype ValueType
        var value: ValueType? { get }
    }
    
    extension WeakValue {
        public var anyValue: Any? { return value }
    }
    

    创建类弱继承 韦克瓦卢

    open class Weak<Value: AnyObject>: WeakValue {
        public init(value: Value?) { self.value = value }
        open private(set) weak var value: Value?
    }
    

    使用示例

    private var _delegates: [AnyWeakValue] = []
    public var delegates: [SomeProtocol] {
        return _delegates.compactMap({$0.anyValue as? SomeProtocol})
    }
    
    public func register<Delegate>(_ delegate: Delegate) where Delegate: SomeProtocol {
        let weak: Weak<Delegate> = Weak.init(value: delegate)
        _delegates.append(weak)
    }