从UITableViewCell保存到UserDefaults会导致Swift 4.2崩溃

时间:2018-11-13 08:54:30

标签: swift uitableview nsuserdefaults swift4.2

将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时仍然会导致崩溃。

我认为这与TableViewCell的出队性质有关,但我不了解发生了什么,因此不确定如何解决此问题。

编辑: 单身人士

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)上。 我在那条线上设置了一个断点,当我按下steps时,发生EXC_BAD_ACCESS

1 个答案:

答案 0 :(得分:0)

我发现了错误。这是因为有观察员。 tableView中还有另一个单元格,该单元格具有该状态的观察者。我没有在deinit上删除观察者,因此每次使单元出队并重绘时,都会添加观察者的多个实例。

所有人都可以观察到为同一参考对象创建观察者的次数。我不会走得很远,总是会在deinit上删除,有时甚至不会调用deinit。示例:tabbarcontroller上的viewcontroller。 比较安全的选择是观察创建实例的数量。在这种情况下,我应该删除deinit

上的观察者

感谢所有发表评论并帮助推动事情发展的人