类型A要求类型B是类型swift 4

chr*_*low 16 swift swift4

以下代码给出了编译错误

'WeakReference'要求'ServiceDelegate'是类类型

protocol ServiceDelegate: AnyObject {
    func doIt()
}

class SomeClass() {
    // compile error occurs in this line
    private var observers = [WeakReference<ServiceDelegate>]()
}
Run Code Online (Sandbox Code Playgroud)

WeakReference代码:

final class WeakReference<T: AnyObject> {

    private(set) weak var value: T?

    init(value: T?) {
        self.value = value
    }
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个错误?应根据此站点正确声明委托.

到目前为止我尝试了什么:

  • 从更改委托协议的一致性AnyObject,以 class不解决问题.
  • 在干净的操场上试试上面的代码.

dan*_*dan 14

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

您需要SomeClass将泛型类型用作泛型类型WeakReference

class SomeClass<T: ServiceDelegate> {
    private var observers = [WeakReference<T>]()
}
Run Code Online (Sandbox Code Playgroud)

如果generic on SomeClass过于狭窄,并且您希望能够以多个不相关类的实例作为观察者,那么我将通过放弃on的generic参数来做到这一点WeakReference

final class WeakServiceDelegate {
    private(set) weak var value: ServiceDelegate?

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

class SomeClass {
    private var observers = [WeakServiceDelegate]()
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使WeakReference条件符合ServiceDelegate

extension WeakReference: ServiceDelegate where T: ServiceDelegate {
    func doIt() {
        value?.doIt()
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用ServiceDelegatein 数组SomeClass

class SomeClass {
    private var observers = [ServiceDelegate]()

    func addObserver<T: ServiceDelegate>(_ observer: T) {
        observers.append(WeakReference(value: observer))
    }
}
Run Code Online (Sandbox Code Playgroud)


OOP*_*Per 6

如您所见,ServiceDelegate它是协议,而不是类类型。即使所有可以遵循的ServiceDelegate类型都是类类型,ServiceDelegate它本身也不是类类型。当前是纯Swift协议的事实。

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

@objc protocol ServiceDelegate {
    func doIt()
}
Run Code Online (Sandbox Code Playgroud)

您可能想要排除Objective-C某些东西,并使某些纯Swift类符合ServiceDelegate,但是我找不到其他解决方法。


Vya*_*lav 5

问题是WeakReference<ServiceDelegate>线路错误

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

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

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

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

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

并使用这种方式:

 private var observers = [SomeContainer]()
Run Code Online (Sandbox Code Playgroud)

笔记

使用这种方式:

class SomeClass<T: ServiceDelegate> {
    private var observers = [WeakReference<T>]()
}
Run Code Online (Sandbox Code Playgroud)

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