Переменная Singleton не обновляется - PullRequest
0 голосов
/ 02 марта 2020

Значение переменной 'switcheroo' в контроллере вида ниже всегда одинаково, когда я пытаюсь получить к нему доступ через одноэлементный файл. Я пытаюсь получить доступ к его значению из пользовательского класса меток, который печатает символы метки один за другим. Когда метка установлена, я пытаюсь получить обновленное значение switcheroo в синглтоне Viewcontroller. Однако он всегда возвращает начальное значение switcheroo, а не обновленное значение (которое я могу проследить в viewcontroller). Я делаю что-то неправильно?

class TheViewController: UITableViewController, UIGestureRecognizerDelegate, UITabBarControllerDelegate {

   static let shared = TheViewController()
   var switcheroo = 0

   ... various operations that change the value of switcheroo...
}

class CustomLabel: UILabel {

  required init?(coder aDecoder: NSCoder) {
     super.init(coder: aDecoder)
  } 

  override var attributedText: NSAttributedString? {

    didSet { 

        DispatchQueue.main.async {

          let characterDelay = TimeInterval(0.01 + Float(arc4random()) / Float(UInt32.max)) / 100

                for (index, _) in attributedText.string.enumerated() {

                    DispatchQueue.main.asyncAfter(deadline: .now() + characterDelay * Double(index)) {
                        print("switcheroo value in TheViewController is now: \(TheViewController.shared.switcheroo)")
                        super.attributedText = attributedText.attributedSubstring(from: NSRange(location: 0, length: index+1))
                    }
                }
            }
}

Ответы [ 3 ]

0 голосов
/ 02 марта 2020

Я бы не советовал делать контроллер представления синглтоном исключительно для некоторого общего состояния или свойства модели. Контроллеры представлений имеют свои собственные шаблоны жизненного цикла (например, созданные из сцен раскадровки, выпущенные после их закрытия, воссозданные при повторном представлении и т. Д. c.), И у вас могут возникнуть проблемы, возникающие при работе с отдельными экземплярами вашего представления controller (s).

Вместо этого не пытайтесь бороться со жизненным циклом стандартного контроллера представления, а просто переместите это свойство в отдельный объект, например

final class StateManager {
    static let shared = StateManager()

    var switcheroo = 0

    private init() { }
}

Тогда ваше представление контроллеры могут использовать это:

class ViewController: UIViewController {

    ...

    func examineSwitcheroo() {
        print(StateManager.shared.switcheroo)
    }

    func updateSwitcheroo(to value: Int) {
        StateManager.shared.switcheroo = value
    }
}

Таким образом, вы наслаждаетесь этим общим состоянием, не путая нормальные жизненные циклы контроллера представления в этом процессе.

Теперь, какое правильное имя для этого синглтона, StateManager в моем примере полностью зависит от того, что это общее свойство. Но недостаточно информации о том, что на самом деле этот switcheroo объект может предложить лучший совет по этому вопросу.

И, вероятно, само собой разумеется, это отдельный вопрос относительно того, следует ли вам вообще использовать синглеты вообще для переменных состояния и объектов модели, но это выходит за рамки этого вопроса.

0 голосов
/ 02 марта 2020

Не управляйте данными вашего приложения в контроллерах вашего представления. В платформах Cocoa и Cocoa Touch используется парадигма M V C, где M означает модель , то есть данные приложения модель . Любые данные, которые необходимо сохранить или которые выходят за рамки контроллера представления, должны храниться и управляться в объекте модели. Если при создании вы даете своему контроллеру представления ссылку на модель, вам не нужно беспокоиться о передаче данных из одного контроллера представления в другой; вместо этого каждый из них оперирует моделью, и любые необходимые данные поступают из модели.

0 голосов
/ 02 марта 2020

Если вы определили, что наличие ViewController синглтона является правильным решением, вероятный ответ заключается в том, что вы не используете этот общий экземпляр каждый раз, вместо этого случайно вызываете инициализатор в какой-то момент в вашем проекте (возможно, Xcode делает это автоматически через интерфейсы).

Для поиска по всему проекту вы можете использовать cmd + shift + F и затем набрать TheViewController(). Должен быть только один экземпляр (общий экземпляр). Обязательно проверьте также TheViewController.init(). Это найдется в любое время, когда вы это сделаете.

Если проблема не устранена, возможно, попробуйте установить для общего экземпляра значение self в методе viewDidLoad для TheViewController?

Надеюсь, это поможет !

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