Быстрый typealias с проблемой протокола

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

typealias ViewThatConformsToProtocol = UIView: MyCustomProtocol

и это тоже не работает:

typealias ViewThatConformsToProtocol = UIView, MyCustomProtocol

Но я не хочу использовать для этого подклассы. Есть ли способ сделать это?

P.S. С подклассами мне бы хотелось так:

class ViewThatConformsToProtocol: UIView, MyCustomProtocol {

}

Но я не хочу использовать подклассы, потому что это противоречит моему шаблону проектирования (например, потому что, когда мне просто нужно знать, что мое представление поддерживает поведение этого протокола, я не хочу, чтобы это представление было подклассом ViewThatConformsToProtocol . И иногда View1 может подтверждают протокол 1 и протокол 2, но View2 может соответствовать протоколам 1 и 3 — это просто для примера). В Objective-C вы можете легко объявить UIView *viewForProtocol = (UIView<MyCustomProtocol> *)view1 , но в SWIFT это кажется невозможным, поэтому я ищу обходной путь


person Paul T.    schedule 20.04.2017    source источник
comment
Я не совсем понимаю, чего вы хотите добиться. Можете ли вы показать нам, как бы вы это сделали, если бы использовали для этого подклассы?   -  person Sweeper    schedule 20.04.2017
comment
@Sweeper, я добавил код и комментарии.   -  person Paul T.    schedule 20.04.2017
comment
@MaxPevsner, эта статья не помогла   -  person Paul T.    schedule 20.04.2017
comment
Итак, вам нужен псевдоним типа UIView или подкласс UIview и он соответствует MyCustomProtocol?   -  person Sweeper    schedule 20.04.2017
comment
@Sweeper, только UIView, который соответствует MyCustomProtocol, а не подклассу UIView   -  person Paul T.    schedule 20.04.2017
comment
Но есть только один класс с именем UIView. Этот класс либо соответствует MyCustomProtocol, либо нет. Это можно определить во время компиляции.   -  person Sweeper    schedule 20.04.2017
comment
@Sweeper, я понимаю, но как мне реализовать Objective-C UIView *viewForProtocol = (UIView‹MyCustomProtocol› *)view1 в SWIFT?   -  person Paul T.    schedule 20.04.2017
comment
Извините, я не очень хорошо читаю код Objective-C...   -  person Sweeper    schedule 20.04.2017


Ответы (3)


typealias DesiredAlias<T> = T where T:MyCustomProtocol

//you can assign type like below
var variableThatConformsToProtocol: DesiredAlias<MyCustomProtocol>

Может быть, этот фрагмент кода соответствует вашим требованиям? На самом деле он принимает любой тип, соответствующий MyCustomProtocol, поэтому он похож на id<MyCustomProtocol> variableThatConformsToProtocol в Objective-C.

person kamil3    schedule 21.04.2017

На самом деле предложение @MaxPevsner было правильным, но не точным. Вам не нужно использовать typealias, так как всю магию могут делать дженерики.

protocol MyCustomProtocol {
    // ...
}

class MyCustomView: UIView, MyCustomProtocol {

}

class MyClass<T> where T: MyCustomProtocol {

    func someFunction<T>(_ value: T) {
        self.property = value
    }
}

// ...
let view = MyCustomView()
let trick = MyClass<MyCustomView>()
trick.someFunction(view)

Соответствует ли он вашим требованиям?

person Daniyar    schedule 20.04.2017
comment
на самом деле нет, потому что здесь нам не очень нужен AnotherCustomProtocol, потому что мне нужно сделать как в Objective-C UIView *viewForProtocol = (UIView‹MyCustomProtocol› *)view1 во многих методах (я конвертирую код Objective-C в SWIFT ) - person Paul T.; 20.04.2017

Псевдоним типа — это псевдоним определенного типа. Вы просите что-то, что соответствует набору условий

Учитывая фрагмент кода, который вы разместили

UIView *viewForProtocol = (UIView<MyCustomProtocol> *)view1 

Эквивалентный быстрый код будет

let viewForProtocol = view1 as? MyCustomProtocol as ? UIView
person adamfowlerphoto    schedule 20.04.2017
comment
Думаю, у вас есть дескриптор UIView или MyCustomProtocol. Вы не можете иметь оба - person adamfowlerphoto; 20.04.2017