扩展属性不作为实例属性

时间:2017-05-19 12:09:16

标签: swift protocols swift-extensions

我创建了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
    }
  }
}

1 个答案:

答案 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组件和视图控制器,这通常不是问题。