Как объявить свойство определенного класса, который также соответствует протоколу?

Предположим, я хочу создать свойство, которое является подклассом UIViewController, а также соответствует протоколу MyDelegateProtocol. В Objective-C я бы написал что-то вроде:

@property (strong, nonatomic) UIViewController<MyDelegateProtocol> *delegate; 

Однако я не уверен, как это записать в Swift. Я знаю, как объявить свойство, которое соответствует протоколу, или свойство, которое имеет определенный тип:

 let delegate : MyDelegateProtocol? let delegate : UIViewController? 

Но я не могу понять, как это сделать. Если я попробую что-то вроде:

 let delegate : UIViewController<MyDelegateProtocol> ? 

Затем я получаю сообщение об ошибке компилятора. Cannot specialize non-generic type 'UIViewController' . Наверное, потому что я сейчас блуждаю по земле дженериков. Я пробовал просматривать книгу Swift по протоколам и другим вопросам переполнения стека в отношении протоколов, но я не нашел совершенно то, что искал.

Прежде всего, я думаю, что это запах кода. Если вы хотите, чтобы делегат был несколькими вещами, скорее всего, проблема разделения проблем.

С учетом сказанного, если вы все еще хотите это сделать, в Swift нет никакого способа. У вас есть несколько вариантов:

  1. Добавьте необходимые методы UIViewController в ваш протокол делегатов ( мой любимый вариант )
  2. Создайте суперкласс для вашего контроллера представлений, который является подклассом UIViewController и реализует MyDelegateProtocol. Объявите свою переменную как этот тип
  3. Сохраните две ссылки на ваш «делегат». Один из MyDelegateProtocol, а другой – UIViewController
  4. Сделайте свой класс общим, но это не будет доступно из Objective-C

Отвечая на мой собственный вопрос полтора года спустя, чтобы указать кому-либо в будущем на эту статью , которая в основном отвечает на вопрос в Swift 2. Это не совсем возможно, но с использованием расширений протокола вы можете приблизиться.

Отвечая на мой собственный вопрос через 3 года, Swift 4 поддерживает комбинированные типы классов и протоколов:

 let delegate: UIViewController & MyDelegateProtocol 

Один из вариантов заключается в параметризации всего вашего класса; К сожалению, классы шаблонов не могут использоваться из Obj-C.

 class MyClass<Delegate: protocol<UIViewController, MyDelegateProtocol>> { ... let delegate: Delegate? ... } 
  • Обновление данных в UIViewController после отклонения представленного им контроллера модального представления через делегата
  • Расширения и подклассы протокола
  • Как использовать делегаты для передачи данных из пользовательской ячейки в метку в родительском представлении
  • Попытка понять протокол / делегатов в Swift
  • Почему мой делегат недействителен?
  • Расширение протокола для некоторых UIControls
  • Obj-C: метод делегирования не вызван
  • Наличие класса Swift как подкласс UIViewController, так и UITableViewDelegate
  • Доступ к членам типа протокола не работает в Swift
  • Ошибка переопределения функции в быстром
  • Как использовать протоколы цели-c
  • Давайте будем гением компьютера.