简单协议继承一致性的解决方法
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
}
}
}
在我们的应用程序中,我们有一项服务可以帮助我们决定接下来应该呈现哪个模式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
}
}
}