我在调用此方法时遇到问题:
func setUpFeedbackForm<T:UIViewController>(viewController: T,
viewForScreenshot: UIView,
completionHandler: @escaping () -> ())
where T:FeedbackFormDelegate { ... }
在这个包装函数中:
public class func setUpFeedbackFormWrapper(viewController: UIViewController,
viewForScreenshot: UIView,
completionHandler: @escaping () -> ()) {
setUpFeedbackForm(viewController: viewController,
viewForScreenshot: viewForScreenshot,
completionHandler: completionHandler)
}
我收到错误:通用参数&#39; T&#39;无法推断。我确实理解错误的含义,但我不知道如何正确实现此调用。我之所以拥有这个包装器,也是因为我希望将func setUpFeedbackForm
公开给obj-c代码而且我不能直接将它导入到obj-c中,因为它的泛型。
你能告诉我正确的召唤方式吗?
答案 0 :(得分:2)
调用viewController
时,您需要满足setUpFeedbackForm
参数的两个约束:
UIViewController
FeedbackFormDelegate
,setUpFeedbackFormWrapper
只满足一个,因此编译器不知道如何处理另一个。
问题是由Swift的限制引起的,Swift不能直接表示满足类继承和协议一致性的变量/参数,除非使用泛型,这会破坏Objective-C
兼容性。
因此,UIViewController<FeedbackFormDelegate>
中的有效Objective-C
结构在Swift
中没有直接等效结构。
此限制的解决方法是声明第3个方法,该方法将类继承和协议一致性参数公开为两个不同的参数,并从Objective-C
兼容和Swift
调用该方法 - 仅版本
func setUpFeedbackForm<T:UIViewController>(viewController: T,
viewForScreenshot: UIView,
completionHandler: @escaping () -> ())
where T:FeedbackFormDelegate {
setupFeedbackFormImpl(viewController: viewController,
feedbackFormDelegate: viewController,
viewForScreenshot: viewForScreenshot, completionHandler: completionHandler)
}
func setupFeedbackFormImpl(viewController: UIViewController,
feedbackFormDelegate: FeedbackFormDelegate,
viewForScreenshot: UIView,
completionHandler: @escaping () -> ()) {
// actual code here
}
public func setUpFeedbackFormWrapper(viewController: UIViewController,
viewForScreenshot: UIView,
completionHandler: @escaping () -> ()) {
guard let feedbackFormDelegate = viewController as? FeedbackFormDelegate else {
// you can also report errors here, if you want to
// forbid runtime calls with controllers that are not FeedbackFormDelegate
return
}
setupFeedbackFormImpl(viewController: viewController,
feedbackFormDelegate: feedbackFormDelegate,
viewForScreenshot: viewForScreenshot,
completionHandler: completionHandler)
}
如果我们考虑SOLID
编程,那么这个解决方法遵循接口隔离原则,因为我们收到一个视图控制器东西的参数,另一个参与委托的东西,即使他们指向同样的对象背后。