使用UserDefaults保存数据报非属性列表对象插入错误如何解决
点击保存触发的报错翻译如下:
线程1报错:"尝试插入非属性列表对象 <UITextField: 0x7fea4d02ca00; frame = (20 85; 374 34); opaque = NO; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x600002cb65b0>;; placeholder = Name; borderStyle = RoundedRect; background = <_UITextFieldSystemBackgroundProvider: 0x6000022fa7c0: backgroundView=<_UITextFieldRoundedRectBackgroundViewNeue: 0x7fea4c7107c0; frame = (0 0; 374 34); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x6000022fa7e0>>, fillColor=(null), textfield=<UITextField 0x7fea4d02ca00>>; layer = <CALayer: 0x6000022fa580>> 对应键 personName"
崩溃的核心原因是你往UserDefaults中传入了不支持存储的类型:UserDefaults仅支持存储属性列表类型(NSString、NSNumber、NSData、NSDate、NSArray、NSDictionary),你在保存逻辑里直接把UITextField控件实例存了进去,没有取输入框内的文本值,自然触发报错。
你当前保存按钮的代码存在两处核心错误:
// 错误:传入的是nameTextField控件对象,不是输入框内的字符串内容 UserDefaults.standard.set(nameTextField!, forKey: "personName") // 错误:传入的是birthdayTextField控件对象,不是输入框内的字符串内容 UserDefaults.standard.set(birthdayTextField, forKey: "personDate") nameLabel.text = "Name: \(nameTextField.text!)" birthdayLabel.text = "Birthday: \(birthdayTextField.text!)"
另外viewDidLoad中的读取逻辑也有小问题:读取后给标签赋值没有和保存逻辑保持一致的前缀格式,会导致首次加载本地数据时显示内容和保存后格式不统一,而且用object(forKey:)再强转String的写法不如直接用专属取值方法安全。
修正保存按钮点击逻辑
存储时取输入框的text属性,同时做空值兜底,避免强制解包引发的异常:
// 安全获取输入内容,空值默认用空字符串兜底 let inputName = nameTextField.text ?? "" let inputBirthday = birthdayTextField.text ?? "" // 存储字符串类型的输入内容,而非控件本身 UserDefaults.standard.set(inputName, forKey: "personName") UserDefaults.standard.set(inputBirthday, forKey: "personDate") // 标签赋值保持格式统一 nameLabel.text = "Name: \(inputName)" birthdayLabel.text = "Birthday: \(inputBirthday)"
修正viewDidLoad读取逻辑
直接用string(forKey:)读取字符串值,赋值时保持格式和保存逻辑一致:
// 直接读取字符串类型值,空值兜底 let storedName = UserDefaults.standard.string(forKey: "personName") ?? "" let storedDate = UserDefaults.standard.string(forKey: "personDate") ?? "" if !storedName.isEmpty { nameLabel.text = "Name: \(storedName)" } if !storedDate.isEmpty { birthdayLabel.text = "Birthday: \(storedDate)" }
内容的提问来源于stack exchange,提问作者althebeast

