我创建了UIImageView的协议扩展,并在扩展名中添加了一个bool属性 isFlipped 。我的问题是,如果我将 isFlipped 设置为false,则对于一个对象,将为所有UIImageView对象设置相同的值。任何人都可以指导如何为每个UIImageView对象单独处理它。
protocol FlipImage {
var isFlipped: Bool { get set }
}
var flippedValue = false
extension UIImageView:FlipImage{
var isFlipped: Bool {
get {
return flippedValue
}
set {
flippedValue = newValue
}
}
}
答案 0 :(得分:1)
如果你想使用扩展添加存储的属性,这里使用的一个小技巧允许你为你可以覆盖的基类(即视图控制器,我使用它的那个)执行它:
此协议允许使用扩展和协议中的存储属性扩展基类:
protocol ExtensibleObject:class
{
var extendedProperties:[String:Any] { get set }
}
extension ExtensibleObject
{
func get<T>(_ defaultValue:T, _ file:String = #file, _ line:Int = #line) -> T
{
return (extendedProperties["\(file):\(line)"] as? T) ?? defaultValue
}
func set<T>(_ newValue:T, _ file:String = #file, _ line:Int = #line)
{
return extendedProperties["\(file):\(line)"] = newValue
}
}
要使用该协议,您需要创建基类的子类,以便为所有扩展属性添加存储(对于类及其所有子类)。
class ExtensibleViewController:UIViewController, ExtensibleObject
{
var extendedProperties:[String:Any] = [:]
}
请注意,如果是基类,可以直接在基类中完成。
然后你会使用&#34;可扩展的&#34;您自己的子类而不是基类的基类:
class MyVC:ExtensibleViewController
{}
从那时起,任何子类都可以接收新的&#34;存储&#34;扩展中的属性:
extension MyVC
{
var newStoredProperty:Int
{ get { return get(0) } set { set(newValue) } } // set and get must be on same line
}
对于实现ExtensibleObject协议的类,还可以通过协议采用存储的属性:
protocol ListManager:ExtensibleObject
{
var listContent:[String] { get set }
}
extension ListManager
{
var listContent:[String]
{ get { return get([]) } set { set(newValue) } }
}
extension MyVC:ListManager {}
请记住,这些扩展属性表现为惰性变量,并且在使用时会有一些额外的开销。对于UI组件和视图控制器,这通常不是问题。