代码之家  ›  专栏  ›  技术社区  ›  Leem

如何定义协议扩展中可设置和获取的变量

  •  1
  • Leem  · 技术社区  · 6 年前

    我想在Swift中实现抽象类,我知道在Swift中没有抽象类的概念。但我知道我们可以通过使用协议在Swift中模仿这个概念。例如,我试过:

    // With protocol, I can define functions that concrete class have to implement
    protocol ProductProvider {
       func getProductNumber() -> Int
    }
    
    // with protocol extension, I can define shared (computed) properties and functions among concrete classes that comply with this protocol
    extension ProductProvider {
      var maxProductCount: Int {
            return 10
      }
    }
    

    extension ProductProvider {
      var maxProductCount: Int {
            set(newValue) {
               // set to what if I couldn't define private stored variable in extension to hold the most recent set value ?
            }
            get{
               // how to return the most recent value set?
            }
      }
    }
    

    我的问题在上述代码的注释中。如何在swift4协议扩展中设置和获取变量?如果这是不可能的,什么是可行的变通办法?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Oni_01    5 年前

    举个例子:

    protocol AbstractObject {
    
        var maxProductCount: Int { get set }
    }
    
    struct ConformObject: AbstractObject {
    
        var maxProductCount: Int
    }
    

    所以现在可以在默认实现中使用变量

    extension AbstractObject {
    
        mutating func addOne() -> Int {
            self.maxProductCount += 1
            return self.maxProductCount
        }
    } 
    
        2
  •  1
  •   Ehsan Saddique    6 年前

    除了讨论它是否是实现所需目标的正确方法之外,还可以使用对象关联。

    public final class ObjectAssociation<T: AnyObject> {
    
        private let policy: objc_AssociationPolicy
    
        /// - Parameter policy: An association policy that will be used when linking objects.
        public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
    
            self.policy = policy
        }
    
        /// Accesses associated object.
        /// - Parameter index: An object whose associated object is to be accessed.
        public subscript(index: AnyObject) -> T? {
    
            get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? }
            set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) }
        }
    }
    

    extension SomeType {
    
        private static let association = ObjectAssociation<NSObject>()
    
        var simulatedProperty: NSObject? {
    
            get { return SomeType.association[self] }
            set { SomeType.association[self] = newValue }
        }
    }
    


    资料来源: https://stackoverflow.com/a/43056053/1811810