Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift覆盖子类的所有setter和getter_Swift_Realm - Fatal编程技术网

Swift覆盖子类的所有setter和getter

Swift覆盖子类的所有setter和getter,swift,realm,Swift,Realm,我想覆盖一次setter/getter,但不覆盖swift中类的所有属性 这是我的课。每次添加新值时,我都要调用Realm class House : Object { var a:String { set { do { let realm = try Realm() try realm.write { a = newValue

我想覆盖一次setter/getter,但不覆盖swift中类的所有属性

这是我的课。每次添加新值时,我都要调用
Realm

class House : Object
{
    var a:String
    {
        set {
            do {
                let realm = try Realm()
                try realm.write {
                    a = newValue
                }
            }
            catch {

            }
        }
    }


    var b:String
    {
        set {
            do {
                let realm = try Realm()
                try realm.write {
                    b = newValue
                }
            }
            catch {

            }
        }
    }
}

有一种方法可以达到海报想要的效果,但是可能不可取。。。无论如何您可以创建自己的赋值运算符,在赋值之前,该运算符可以在领域中执行任何您想执行的操作

class MyType {        
    var myInt : Int = 0
    var myString : String = ""

    init(int: Int, string: String) {
        myInt = int
        myString = string
    }
}

infix operator === {}
func ===<T>(lhs: T, rhs: T) -> T? {
    Realm() // replace with whatever Realm()-specific stuff you want to do
    return rhs
}

protocol MyAddableTypes {
    func + (lhs: Self, rhs: Self) -> Self
}

extension String : MyAddableTypes {}
extension Int : MyAddableTypes {}

infix operator +== {} // ... -== similarily
func +==<T: MyAddableTypes>(lhs: T, rhs: T) -> T? {
    Realm() // replace with whatever Realm()-specific stuff you want to do
    return lhs+rhs
}

func Realm() {
    // ...
    print("Called realm")
}

var a = MyType(int: 1, string: "foo")
a.myString === "bar" // calls Realm(). After operation: a.myString = "bar"
a.myInt +== 1 // calls Realm(). After operation: a.myInt = 2

在Swift中,无法同时覆盖所有属性的setter

不过,您通常可以使用:

  • 每个属性覆盖设置器
  • 包装低级属性的抽象计算属性
  • 通过KVC访问器方法(例如,
    is
    get
    ,…)截取getter和setter,如果您想应用修饰行为(出于这个原因,您可能希望避免),则只依赖通过
    valueForKey(Path):
    )进行的基于KVC的非类型动态访问
  • 但是Realm在后台使用自定义getter和setter,它们在运行时在动态插入的中间类中被动态覆盖,并且依赖于它们的存在。因此,唯一真正可行的方法是声明
    dynamic
    存储的属性,并基于这些属性为每个属性添加一个额外的属性

     var storedPropertyA: String = ""
     var computedPropertyA: String {
          get {
              // add your extra behavior here
              return storedPropertyA
          }
          set {
              // add your extra behavior here
              self.storedPropertyA = newValue
          }
     }
    
    除此之外,还有另一种方法可以使用装饰器模式,并用额外的行为装饰整个对象。在Swift中,您可以让您的对象和装饰器实现一个公共协议,该协议定义了您的属性

    protocol HousingProperties {
        var a: String { get set }
    }
    
    class House: HousingProperties {
        var a: String = ""
    }
    
    class HouseDecorator: HousingProperties {
        internal var house: House
    
        init(house: House) { self.house = house }
    
        var a: String {
             // add your extra behavior here
             self.house.a = a
        }
    }
    

    尽管如此,我还是建议拦截属性设置器和获取器,以达到您在这里想要达到的目的。相反,我建议您以某种方式构造应用程序的体系结构,这样可以让您知道是否存在写事务,并让编写事务的责任掌握在试图修改对象的代码手中

    让我解释一下原因:
    Realm使用多版本并发控制算法来管理持久化数据并实现线程安全。这确保了不同的线程可以在任何时间点读取数据,而无需读取锁并尝试同步这些数据。相反,当写入发生时,会通知所有访问器有新数据,并尝试转移到最新的事务。在此之前,必须保留线程仍在使用的最旧数据版本和写入的数据版本之间的所有版本。当所有线程都提升其提交指针时,可以首先释放它们。如果您执行大量小事务,您的文件大小可能会被放大到不必要的高值。因此,我们建议批量将事务写入大型变更集。

    我不确定是否理解您的问题。是什么阻止你覆盖属性
    override var propertyName{get{//body}set{//body}}
    我想海报想要对所有类属性的get/set做一个通用的重写(不管类型如何?)。我想创建一个集合方法,所有属性都可以使用它。你能给出更多的零售,也许还有你想要实现的示例吗?这帮助我们(尝试)帮助你。我添加了更多关于领域的信息。问题中显示的对象继承自
    对象
    ,您必须使用该类在模式中定义持久化对象。因此,在执行类似操作时,您应该注意性能影响。
    protocol HousingProperties {
        var a: String { get set }
    }
    
    class House: HousingProperties {
        var a: String = ""
    }
    
    class HouseDecorator: HousingProperties {
        internal var house: House
    
        init(house: House) { self.house = house }
    
        var a: String {
             // add your extra behavior here
             self.house.a = a
        }
    }