简单协议继承一致性的解决方法

Workaround for simple protocol inheriting conformance

在我们的应用程序中,我们有一项服务可以帮助我们决定接下来应该呈现哪个模式UIVIewController。每个 ModalVIewController 都有共同的功能,例如 dismiss(),但也有它实现的特定功能。这就是我们的尝试:

所有 VC 的基本功能通用的基本协议。

protocol ModalScreenDelegate: AnyObject {
    func modalScreenWantsToDissmiss(_ modalScreen: ModalScreen)
}

每个 UIViewController 实现的基本协议

protocol ModalScreen: UIViewController {
    var delegate: ModalScreenDelegate? { get set }
}

现在我们创建一个协议,具体实现 ModalScreenDelegate 基本协议,如下所示:

protocol ShareToFacebookDelegate: ModalScreenDelegate {
    func someCustomMethod()
}

并将其分配给:

class ShareToFacebookViewController: UIViewController, ModalScreen {
   weak var delegate: ModalScreenDelegate? // **WORKS**
   weak var delegate: ShareToFacebookDelegate? // **DOESN'T WORKS**
}

如果我尝试使用 ShareToFacebookDelegate 而不是 ModalScreenDelegate,编译器会抛出一个 IDE 错误,提示我必须将其改回 ModalScreenDelegate

为什么它不起作用?它ShareToFacebookDelegate 符合ModalScreenDelegate。 任何帮助将不胜感激。 谢谢!

更新基于 Alexandr Kolesnik:

你的方法行得通。但是,当我尝试使用一种方法 "fetch" 服务中的正确 VC 时,如下所示:

func fetchModal<T: ModalScreen & UIViewController>() -> T? {
    return AddInstagramViewController.create() as? T
}

然后有一个协调员想要得到这个 vc:

guard let currentModalViewController vc = modalScreenSupplierService.fetchModal() else {
    return
}

我得到:

Generic parameter 'T' could not be inferred

而且我真的不能说 T 会是什么,我只知道它会符合 UIViewController & ModalScreen。可以解决吗?

这个解决方案:

   protocol ModalScreenDelegate: AnyObject {
        func modalScreenWantsToDissmiss(_ modalScreen: ModalScreen)
    }
    protocol ModalScreen: UIViewController {
        var delegate: (ModalScreenDelegate & ShareToFacebookDelegate)? { get set }
    }
    protocol ShareToFacebookDelegate: ModalScreenDelegate {
        func someCustomMethod()
    }
    class ShareToFacebookViewController: UIViewController, ModalScreen {
       weak var delegate: (ModalScreenDelegate & ShareToFacebookDelegate)? 
    }

或继承:

protocol ModalScreenDelegate: AnyObject {
    func modalScreenWantsToDissmiss(_ modalScreen: ModalScreen)
}
protocol ModalScreen: ShareToFacebookDelegate where Self: UIViewController {
    var delegate: ModalScreenDelegate? { get set }
}
protocol ShareToFacebookDelegate: ModalScreenDelegate {
    func someCustomMethod()
}
class ShareToFacebookViewController: UIViewController, ModalScreen {
    func someCustomMethod() {

    }

    func modalScreenWantsToDissmiss(_ modalScreen: ModalScreen) {

    }

   weak var delegate: ModalScreenDelegate? // **WORKS**
}

如果我对您的理解正确,您可以使用通用类型来解决问题。查看下面的代码。希望对你有帮助

    protocol ModalScreenDelegate: AnyObject {

    typealias T = ModalScreenDelegate

    func modalScreenWantsToDissmiss(_ modalScreen: T)
}

protocol ShareToFacebookDelegate: ModalScreenDelegate {
    func someCustomMethod()
}

protocol ModalScreen: UIViewController {

    associatedtype T

    var delegate: T? { get set }
}


class ShareToFacebookViewController: UIViewController, ModalScreen {

    typealias T = ShareToFacebookDelegate

    weak var delegate: T?

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate?.someCustomMethod()
    }

}

更新:

    class AddInstagramViewController: SuperVC {

    typealias T = ShareToFacebookDelegate

    private var instaDelegate: ShareToFacebookDelegate?

    override var delegate: ModalScreenDelegate? {
        set {
            instaDelegate = newValue as? ShareToFacebookDelegate
        }
        get {
            return instaDelegate
        }
    }

    static func create() -> AddInstagramViewController {
        return AddInstagramViewController()
    }

}

class SuperVC: UIViewController, ModalScreen {

    typealias T = ModalScreenDelegate

    var delegate: T?

}

class Supplier {

    func fetchModal<M: ModalScreen>() -> M? { return AddInstagramViewController.create() as? M }

}

class SupplierImpl {

    let modalScreenSupplierService: Supplier? = nil

    func goto() {
        guard
            let vc: SuperVC = modalScreenSupplierService?.fetchModal()
        else {
            return
        }
    }

}