Swift 简单协议继承一致性的变通方法

Swift 简单协议继承一致性的变通方法,swift,inheritance,protocols,subclass,swift-protocols,Swift,Inheritance,Protocols,Subclass,Swift Protocols,在我们的应用程序中,我们有一项服务可以帮助我们决定下一步应该展示哪个模态UIVIewController。每个ModalVIewController都有共同的功能,例如dismise(),但也有它实现的特定功能。这就是我们所尝试的: 所有VC基本函数通用的基本协议 protocol ModalScreenDelegate: AnyObject { func modalScreenWantsToDissmiss(_ modalScreen: ModalScreen) } 每个UIView

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

所有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的更新:

你的方法有效。但是,当我尝试在服务中使用这样一种方法“获取”正确的VC时:

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

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
        }
    }

}
类AddInstagramViewController:SuperVC{
typealias T=ShareToFacebookDelegate
私有var instaDelegate:ShareToFacebookDelegate?
覆盖变量委托:ModalScreenDelegate{
设置{
instaDelegate=newValue作为?ShareToFacebookDelegate
}
得到{
返回代理
}
}
static func create()->AddInstagramViewController{
返回AddInstagramViewController()
}
}
类SuperVC:UIViewController、ModalScreen{
typealias T=ModalScreenDelegate
var代表:T?
}
类供应商{
func fetchModal()->M{return AddInstagramViewController.create()作为?M}
}
类供应商impl{
let modalScreenSupplierService:供应商?=无
func goto(){
警卫
设vc:SuperVC=modalScreenSupplierService?.fetchModal()
否则{
返回
}
}
}

您不想重命名您的代理以了解您呼叫的是哪一个吗?@AlexandrKolesnik嘿,Alex,我已经大致描述了这个问题,抱歉!请随意编辑我现在在手机上什么不起作用?您收到了什么错误消息?@giorashc如果我试图使用
ShareToFacebookDelegate
而不是
ModalScreenDelegate
编译器抛出一个IDE错误,说我必须将其改回
ModalScreenDelegate
@giorashc,我已经更新了问题。将代码粘贴到操场将导致相同的编译错误。..Hey@Vyacheslav!谢谢你的回答。我想你误解了我(可能是我的错)。我有一个协调人负责展示那些情态动词。我正在尝试创建一个我的协调员可以遵守的基本委托。因此基本上,一些CustomMethod()和modalScreenWantsToDissmiss()应该在协调器上实现,而不是在实际的VC上实现。这还可能吗?我试过在我的项目内部,但似乎它并没有达到这个目的!我们发现的唯一问题是,当我们尝试使用一个基本上期望
ModalScreen
输出的函数时,它不起作用。。。我已经更新了这个问题。你能看一下吗?
    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
        }
    }

}