在Swift的基类中添加一个泛型委托



理想情况下,我想创建一个BaseViewController类,它接受协议类型(委托),并有一个弱变量作为委托。像这样:

class BaseViewController<Delegate: AnyObject> {
    weak var delegate: Delegate?
    init(delegate: Delegate) {
        self.delegate = delegate
        super.init(...)
    }
}

然后像这样从视图控制器继承:

protocol MyDelegate: AnyObject { 
    func funcA()
    func funcB()
}  
class SomeViewController: BaseViewController<MyDelegate> {
    func doSomething() {
        delegate?.funcA()
    }
}

编译器会报错:

'BaseViewController'要求'MyDelegate'是一个类类型

我该如何解决这个问题来实现我所需要的?
提前感谢:)

这是因为在swift协议中不会向它们自己确认,所以你不能使用" myprotocol ";作为确认协议的具体类型"MyDelegate">

你可以做的是

protocol MyDelegate: AnyObject {
    func funcA()
    func funcB()
}
class BaseViewController<Delegate: MyDelegate> {
    weak var delegate: Delegate?
    init(delegate: Delegate) {
        self.delegate = delegate
        super.init(...)
        //keeping OPs code as is
    }
}
class SomeOtherDelegateClass: MyDelegate {
    func funcA() {
        //some code here
    }
    func funcB() {
        //some code here
    }

}
class SomeViewController: BaseViewController<SomeOtherDelegateClass> {
    func doSomething() {
        self.delegate?.funcA()
    }
}

编辑1:

正如OP在评论中提到的那样,他试图在BaseViewController中引入一个泛型属性,该属性将简单地保留对任何实例的弱引用,这些实例的类是由BaseViewController的子类使用泛型决定/声明的,我将上述答案简化了一点

试试这个

protocol MyDelegate {
    func funcA()
    func funcB()
}
class BaseViewController<Delegate> where Delegate: AnyObject {
    weak var delegate: Delegate?
    init(delegate: Delegate) {
        self.delegate = delegate
        super.init(...)
        //keeping OPs code as is
    }
}
class SomeOtherDelegateClass: MyDelegate {
    func funcA() {
        //some code here
    }
    func funcB() {
        //some code here
    }
}
class SomeViewController: BaseViewController<SomeOtherDelegateClass> {
    func doSomething() {
        self.delegate?.funcA()
    }
}
protocol MyDelegate2 {
    func funcABCD()
}
class SomeOtherDelegateClass2: MyDelegate2 {
    func funcABCD() {
        //some code here
    }
}

class SomeViewController2: BaseViewController<SomeOtherDelegateClass2> {
    func doSomething() {
        self.delegate?.funcABCD()
    }
}
老实说,我真的看不出这个设计有什么好处!也许你需要重新审视代码结构,看看你是否能想出更好的代码结构:)

你应该将你的委托设置为BaseViewController中通用类型T的约束:

protocol MyDelegate: AnyObject {
    func funcA()
    func funcB()
}
class Delegated1: MyDelegate {
    func funcA() { print("A1") }
    func funcB() {}
}
class Delegated2: MyDelegate {
    func funcA() { print("A2") }
    func funcB() {}
}
class BaseViewController<T: MyDelegate>: UIViewController {
    var delegate: T?
    func doSomething() {
        delegate?.funcA()
    }
}
class SomeViewController1: BaseViewController<Delegated1> {}
class SomeViewController2: BaseViewController<Delegated2> {}
class TestClass {
    let viewController1: SomeViewController1 = {
        let viewController = SomeViewController1(nibName: nil, bundle: nil)
        viewController.delegate = .init()
        return viewController
    }()
    let viewController2: SomeViewController2 = {
        let viewController = SomeViewController2(nibName: nil, bundle: nil)
        viewController.delegate = .init()
        return viewController
    }()

    // prints:
    // A1
    // A2
    func myFunc() {
        viewController1.doSomething()
        viewController2.doSomething()
    }
}

最新更新