Использование переопределенного статического свойства во время инициализации - PullRequest
0 голосов
/ 05 октября 2018

Я хотел бы создать класс со статическим свойством, которое подклассы могут переопределять, который будет использоваться для инициализации экземпляров.До сих пор я пытался сделать это следующим образом:

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 голосов
/ 05 октября 2018

Вы можете сделать это с помощью этого подхода

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"
0 голосов
/ 05 октября 2018

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, ленивый не является выбором для ОП.Альтернативное решение, которое не использует ленивую переменную, - это использование свойства «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'
0 голосов
/ 05 октября 2018

Если вы наследуете от 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...