在初始化过程中使用的重写静态属性(Using an overriden static propert

2019-10-29 08:05发布

我想创建一个类的静态属性,子类可以重写,这将被用来初始化实例。 到目前为止,我试图做到这一点是这样的:

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总之,我试图建立具有几个一对多关系到其他车型领域模型类。 对于这些模型(这是非常相似),我试图创建一个包含共享功能的超类,除这也是反比关系。 因此,我想有一个包含在第一模式或者其他模式的关键静态属性,然后初始化使用此键名LinkingObjects属性。 由于境界不允许这种偷懒或计算,我不能在这里使用这些功能。

Answer 1:

如果您为什么不使用它从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"
    }
}



Answer 2:

你可以用这种形式给出这样做

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"


Answer 3:

A.staticProperty将使用静态调度和总是指向A的类属性。 你所需要的动态调度,又名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

PS的private(set)的部分只是我平时做的,我很少让外在因素改变我的对象。

更新作为@MartinR指出,懒惰是不是为OP选择。 不使用一个懒惰的VAR另一种解决方案是使用“阴影”属性:

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'


文章来源: Using an overriden static property during initialization