编写包含另一个通用协议的通用协议是正确的方法吗

时间:2020-07-27 11:15:51

标签: ios swift

我尝试用以下关联类型描述协议:

protocol SomeViewRelativeProtocol {
    associatedtype ViewType: UIView
    
    var view: ViewType
}


protocol SomeProtocolContainMultipleSomeViewRelativeProtocol {
   var views: [SomeViewRelativeProtocol]

// error :  Protocol 'SomeViewRelativeProtocol' 
// can only be used as a generic constraint because 
// it has Self or associated type requirements
}

所以我可以这样使用那些协议:

class Button: SomeViewRelativeProtocol {
    var view: UIButton = UIButton()
}

class Label: SomeViewRelativeProtocol {
    var view: UILabel = UILabel()
}

// then I want do some thing like this

class SomeContainer: SomeProtocolContainMultipleSomeViewRelativeProtocol {
   var views: [SomeViewRelativeProtocol] = []
   
   func add() {
       self.views.append(Button())
       self.views.append(Label())
   }


   func do() {
        self.views.forEach { (item) in
            item.view.frame = .zero
        }
   }
}

我如何描述这种情况,我试图创建一个AnyView类,以使swift知道下面的类型,但是当实现AnyView的子类(Button:AnyView)时,无法将Button类型的值转换为AnyView :

class AnyView: SomeViewRelativeProtocol {
    var view: UIView = UIView()
}


class Button: AnyView {
   var view: UIButton = UIButton()
}

class Label: AnyView {
   var view: UILabel = UIButton()
}

class SomeContainer: SomeProtocolContainMultipleSomeViewRelativeProtocol {
    var views: [AnyView] = []


    func add() {
       self.views.append(Button())
       self.views.append(Label())
       // Cannot convert value of type ....

   }
}

有正确的方法吗?还是一开始我错了?

============================== Updata =============== ================

我想到了一个主意:

protocol SomeViewRelativeProtocol {
    associatedtype ViewType: UIView
    
    var view: ViewType
}


protocol SomeProtocolContainMultipleSomeViewRelativeProtocol {
   // var views: [SomeViewRelativeProtocol]
   // change it to 
   var views: [Any] { get }
   func add<T: SomeViewRelativeProtocol>(item: T) -> Void
   func itemAtIndex<T: SomeViewRelativeProtocol>(index: Int) -> T?
}

那怎么办,我不知道该怎么做,就像函数在属性上使用<T: SomeViewRelativeProtocol>一样

1 个答案:

答案 0 :(得分:0)

您将必须执行以下操作:

protocol SomeViewRelativeProtocol {
    var view: UIView {get}
}


protocol SomeProtocolContainMultipleSomeViewRelativeProtocol {
   var views: [SomeViewRelativeProtocol] {get}
}

class Button: SomeViewRelativeProtocol {
    var view: UIView = UIButton()
}

class Label: SomeViewRelativeProtocol {
    var view: UIView = UILabel()
}

而且,目前由于编译器的限制,它不起作用,而不仅仅是概念上的限制。 它也与:https://bugs.swift.org/browse/SR-522

有关
相关问题