如何创建可以用于2个不同类的通用swift函数?

时间:2016-07-16 06:22:29

标签: ios swift generics

在我的两个班级中,我有以下代码

// Two classes who's code I am trying to reduce using protocols
class class1 {
    var view: viewSubclass1!
    func printName() {
        print("This is the view: \(view)")
    }
}

class class2 {
    var view: viewSubclass2!
    func printName() {
        print("This is the view: \(view)")
    }
}

// The protocol and protocol extension I am trying to create
protocol myProtocol {
    var view: UIView {get set}
    func printName()
}

extension myProtocol {
    func printName() {
        print("This is the view: \(view)")
    }
}

// The subviews of UIView
class viewSubclass1: UIView {}
class viewSubclass2: UIView {}

如您所见,class1class2是不同的类,但具有相同的变量名称:view和相同的函数名称。区别在于view变量的类型不同。

问题:使用协议和协议扩展,如何减少两个类之间的代码?我不想重复代码,因为它们非常相似。我一直在尝试不同的代码变体,但我一直陷入困境。我不太懂。 如何让两个类使用协议和协议扩展来使用相同的代码?

1 个答案:

答案 0 :(得分:1)

<强>(更新)

声明协议和协议扩展:

protocol MyProtocol {
    associatedtype BaseView: UIView
    var view: BaseView! {get set}
    func printName()
}

extension MyProtocol {
    func printName() {
        print("This is the view: \(view)")
    }
}

给出两个UIView的子类:

class ViewSubclass1: UIView {}
class ViewSubclass2: UIView {}

(为了便于阅读,将某些类型的名称大写。)

并声明两个类:

class Class1: MyProtocol {
    var view: ViewSubclass1!
}

class Class2: MyProtocol {
    var view: ViewSubclass2!
}

您会发现printName()Class1都可以使用Class2

这里有一件重要的事情:

如果您将协议中的view声明为var view: UIView {get set},则var view: ViewSubclass1!无法满足协议要求。 (一方面是可选性的差异,另一方面是您无法将UIViewUIView的子类的任何实例分配给view: ViewSubclass1。)

但是很多事情取决于你在公共代码中真正想做的事情。