在初始化期间使用覆盖的静态属性

时间:2018-10-05 17:26:45

标签: swift cocoa realm

我想创建一个具有静态属性的类,子类可以覆盖该属性,该属性将用于初始化实例。到目前为止,我已经尝试完成以下操作:

import Cocoa

class A: NSObject {
    class var staticProperty: String {
        return "A"
    }

    var property: String = A.staticProperty
}

class B: A {
    override class var staticProperty: String {
        return "B"
    }
}

这不起作用,因为B().property仍返回"A"。如何更改此代码,以使property包含子类指定的值?任何帮助将不胜感激!

修改 我想用property的值初始化staticProperty,所以它也可能像这样:

var property: SomeClass = SomeClass(A.staticProperty)

但是,此初始化仍应将"A"用于类A,并将"B"用于类B。

编辑2(在@RakeshaShastri发表评论之后) 对于我的特定用例,我需要property进行存储(以便不进行计算)并且不延迟。

编辑3 简而言之,我正在尝试构建一个Realm模型类,该模型类与其他模型之间存在许多关系。对于这些模型(它们非常相似),我试图创建一个包含共享功能的超类,其中还包括反向关系。因此,我想拥有一个静态属性,该属性包含第一个模型中其他任何一个模型的键,然后使用该键名初始化LinkingObjects属性。由于Realm不允许延迟或计算,因此我不能在这里使用这些功能。

3 个答案:

答案 0 :(得分:0)

如果您继承自NSObject,为什么不使用它呢?

import Cocoa

class A: NSObject {
    var property: String
    public override init() {
        let str = type(of: self).perform(#selector(getter: type(of: self).staticProperty))?.takeUnretainedValue() as! String
        property = str

    }

    @objc class var staticProperty: String {
        return "A"
    }

}

class B: A {
    override class var staticProperty: String {
        return "B"
    }
}

playground output

答案 1 :(得分:0)

您可以使用此方法

class A {
   var prop: String{
       return "A"
   }

 }

class B: A {
  override var prop: String{
      return "B"
   }
}

print(A().prop) // "PRINTS A"
print(B().prop) // "PRINTS B"

答案 2 :(得分:0)

A.staticProperty将使用静态分派,并且将始终指向A的class属性。这里需要动态调度,也就是type(of: self)

但是,self需要一个实例来使用,因此var property: String = type(of: self.staticProperty无法编译。

但是,惰性属性可以解决此限制,因此您可以将property声明为惰性属性:

class A: NSObject {
    class var staticProperty: String {
        return "A"
    }

    private(set) lazy var property: String = { type(of: self).staticProperty }()
}

class B: A {
    override class var staticProperty: String {
        return "B"
    }
}

print(B().property) // B

P.S。 private(set)部分只是我通常要做的事情,我很少允许外部因素来更改我的对象。

更新正如@MartinR所指出的,懒惰不是OP的选择。不使用惰性变量的替代解决方案是使用“ shadowing”属性:

class A: NSObject {
    class var staticProperty: String {
        return "A"
    }

    private var _property: String?
    var property: String {
        get {
            return _property ?? type(of: self).staticProperty
        }
        set {
            _property = newValue
        }
    }
}

class B: A {
    override class var staticProperty: String {
        return "B"
    }
}

let b = B()
print(b.property)  // B
b.property = "B'"
print(b.property) // B'