У вас есть два ограничения на параметр viewController
, которые должны быть удовлетворены при вызове setUpFeedbackForm
:
- наследство от
UIViewController
- соответствие с
FeedbackFormDelegate
и setUpFeedbackFormWrapper
удовлетворяет только один, таким образом, компилятор не знает, что делать с другим.
Проблема связана с ограничением Swift, которое не может напрямую выражать переменные/параметры, которые удовлетворяют как наследованию классов, так и протоколу, за исключением использования дженериков, что нарушает совместимость Objective-C
.
Таким образом, действующая конструкция UIViewController<FeedbackFormDelegate>
в Objective-C
не имеет прямого эквивалента в Swift
.
Обходной путь к этому ограничению заключается в объявлении третьего метода, который предоставляет аргументы согласования класса и протокола в виде двух различных параметров и вызывает этот метод как из совместимого 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
программирования, то этот способ следует интерфейс сегрегация принцип, мы получим один аргумент для материала контроллера представления, а другой для делегата вещи, даже если они указывают на тот же объект позади.
Можете ли вы объяснить, почему вы вообще используете общий? – matt