Сохранение в UserDefaults из UITableViewCell вызывает сбой Swift 4.2 - PullRequest
0 голосов
/ 13 ноября 2018

UISwitch помещается в UITableViewCell, при переключении переключателя требуется сохранить состояние переключателя в UserDefaults.

class SettingsTableViewCell: UITableViewCell {
   @objc fileprivate func switchToggled(_ cellSwitch: UISwitch) {
        if let option = self.option {
            switch option.tag {
            case 1:
                let state = cellSwitch.isOn
                SettingsValues.standard.setState(state)
            default:
                print(">>> Settings Cell >> Tag for option does not exist")
            }
        }
    }
 }

В viewDidLoad он работает нормально и сохраняется в UserDefaults, однако в тот момент, когда выпрокрутите ячейку с экрана, она вышла из строя.Когда вы прокручиваете назад и переворачиваете переключатель, это вызывает сбой:

EXC_BAD_ACCESS(code=1, address=0x20)

SettingsValues ​​- это пользовательский одиночный объект, функция сохраняется в UserDefaults.Я попытался перенести сохранение из UITableViewCell по протоколу в ViewController, но все равно вызывает сбой при сохранении в UserDefaults.

Я чувствую, что это как-то связано с природой dequeue TableViewCell, но я неЯ не понимаю, что происходит, поэтому не уверен, как решить эту проблему.

РЕДАКТИРОВАТЬ: Singleton

final class SettingsValues: NSObject {
   static let standard = SettingsValues()

   private override init() { super.init() }

   @objc dynamic var state: Bool = UserDefaults.standard.bool(forKey: kEnableState) {
       didSet {
           saveSettingsState()
       }
   }

   private func saveSettingsState() {
        UserDefaults.standard.set(state, forKey: kEnableState)
   }

   func setState(_ bool: Bool) {
        self.state = bool
   }
}

Авария на линии UserDefaults.standard.set(state, forKey: kEnableState).Я устанавливаю точку останова на этой линии, и когда я нажимаю шаг, происходит EXC_BAD_ACCESS

1 Ответ

0 голосов
/ 14 ноября 2018

Я нашел ошибку. Это было из-за наблюдателей. В tableView была еще одна камера, в которой был наблюдатель от штата. Я не удалял наблюдателя на deinit, поэтому каждый раз, когда ячейка снималась и перерисовывалась, добавлялось несколько экземпляров наблюдателя.

Урок для всех, кто наблюдает, сколько раз ваши наблюдатели создаются для одного и того же эталонного объекта. Я не пойду так далеко, чтобы всегда снимать на deinit, иногда deinit никогда не будут вызывать. Пример: viewcontroller на вкладке контроллера. Безопаснее было бы посмотреть количество созданных экземпляров. В этом случае я должен был удалить наблюдателя на deinit

Спасибо всем, кто оставил комментарий и помог перемешать вещи

...