【问题标题】:How to add a computed property to Array<T>?如何将计算属性添加到 Array<T>?
【发布时间】:2015-07-04 04:45:49
【问题描述】:

我有:

var _feedbacks: [feedBack]!

我想向 [feedBack] 添加一个属性,以便我可以说:

var _ID = _feedBacks.ID 

我试过了:

extension Array {   
    var ID: String {        
        get { 
            return self.ID
        }

        set {
            self.ID = newValue
        }
    }
}

但是当我尝试设置/获取ID时,编译器会抛出"EXC_BAD_ACCESS"

我也试过了:

import ObjectiveC

private var arrayAssocationKey: Void?

extension Array {
    var ID: String {
        get {
            return objc_getAssociatedObject(self, &arrayAssocationKey) as? String
        }
        set {
            objc_setAssociatedObject(self, &arrayAssocationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
        }
    }
}

但是编译器调用错误`Array does not conform to protocol AnyObject

是否有任何解决方法来设置此属性?

【问题讨论】:

    标签: ios arrays swift generics


    【解决方案1】:

    扩展所有数组以添加 ID 属性似乎有点矫枉过正。我认为您最好创建一个包含 ID 和反馈数组的类,如下所示:

        class feedbackCollection {
            var ID: String?
            var feedbacks: [feedback]?
        }
    

    编辑:

    对该解决方案进行更通用的尝试可能对您有用:

    class IDArray<T> {
        var ID: String
        var items: [T]
        init(ID: String, items: [T]) {
            self.ID = ID
            self.items = items
        }
    }
    

    它会这样使用:

    let ints = IDArray(ID: "1", items: [1, 2, 4])
    
    let strings = IDArray(ID: "2", items: ["test", "this", "thing"])
    
    strings.ID = "8"
    strings.items.append("more")
    

    【讨论】:

      【解决方案2】:

      您要做的是添加存储属性,无论是使用计算属性访问还是直接公开。

      ID 属性将是您想要添加到 Array 类型的新变量,但这是不可能的。数组,以及任何其他类,结构和枚举,在主声明(而不是扩展)中定义它们的存储属性,以便可以在编译时确定该类的实例占用的内存大小/结构/枚举。

      使用扩展添加存储属性是不可能的,因为这会改变内存大小 - 附加属性会增加更多字节。问题是扩展在某些地方(例如,在一个框架中)是可见的,但在其他地方(例如,在另一个框架中)是不可见的 - 使得数组在跨不同边界使用时与其自身不兼容。

      计算的属性变体:

      extension Array {   
          var ID: String {        
              get { 
                  return self.ID
              }
      
              set {
                  self.ID = newValue
              }
          }
      }
      

      不能工作:它在 getter 和 setter 实现中递归地引用自己(参见this answer

      我从未使用过关联对象(更多是出于哲学原因:如果我使用它,听起来我的代码设计很糟糕),但我认为它应该如下使用:

      private var arrayAssocationKey: String?
      
      extension NSArray {
          var ID: String? {
              get {
                  return objc_getAssociatedObject(self, &arrayAssocationKey) as? String
              }
              set {
                  objc_setAssociatedObject(self, &arrayAssocationKey, newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_COPY))
              }
          }
      }
      
      var array = NSArray()
      
      array.ID = "5"
      println(array.ID)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-27
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 2017-12-31
        • 2019-04-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多