ios - 另一个计算变量设置器中的计算变量设置器使应用程序崩溃
问题描述
此代码导致稍后在 EXC_BAD_ACCESS 某处崩溃
SomeLoader().selectedIndex = 1
class SomeLoader {
// MARK: - Public
var selectedIndex: Int? {
get {
return dataStorage.selectedIndex
}
set {
dataStorage.selectedIndex = newValue
}
}
}
这段代码没有崩溃:
SomeLoader().selectedIndex = 1
class SomeLoader {
// MARK: - Public
var selectedIndex: Int? {
get {
return dataStorage.selectedIndex
}
set {
dataStorage.updateSelected(index: newValue)
}
}
}
在哪里:
struct DataStorage<T: Hashable> {
enum Keys: String {
case selectedIndex
}
private func get<U>(forKey key: String) -> U? {
guard let objectData = getData(forKey: key) else {
return nil
}
let object: U? = get(forData: objectData)
return object
}
private func get<U>(forData objectData: Data) -> U? {
return NSKeyedUnarchiver.unarchiveObject(with: objectData) as? U
}
private func save<U>(forKey key: String, object: U) {
let encodedData = NSKeyedArchiver.archivedData(withRootObject: object)
UserDefaults.standard.set(encodedData, forKey: key)
}
}
extension DataStorage {
func updateSelected(index: Int?) {
guard let index = index else {
remove(forKey: Keys.selectedIndex.rawValue)
return
}
saveSelected(index: index)
}
var selectedIndex: Int? {
get {
return get(forKey: Keys.selectedIndex.rawValue)
}
set {
guard let index = newValue else {
remove(forKey: Keys.selectedIndex.rawValue)
return
}
saveSelected(index: index)
}
}
}
为什么?它是一个错误吗?
带有错误和调用堆栈的屏幕截图。该错误稍后出现在代码的另一部分中。
下面的代码在 iOS 中崩溃。但在操场上工作。
//: Playground - noun: a place where people can play
import UIKit
struct DataStorage<T: Hashable> {
enum Keys: String {
case selectedIndex
}
private func get<U>(forKey key: String) -> U? {
guard let objectData = getData(forKey: key) else {
return nil
}
let object: U? = get(forData: objectData)
return object
}
private func get<U>(forData objectData: Data) -> U? {
return NSKeyedUnarchiver.unarchiveObject(with: objectData) as? U
}
private func save<U>(forKey key: String, object: U) {
let encodedData = NSKeyedArchiver.archivedData(withRootObject: object)
UserDefaults.standard.set(encodedData, forKey: key)
}
private func remove(forKey key: String) {
UserDefaults.standard.removeObject(forKey: key)
}
private func saveSelected(index: Int) {
save(forKey: Keys.selectedIndex.rawValue, object: index)
}
private func getData(forKey key: String) -> Data? {
return getContent(forKey: key) as? Data
}
private func getContent(forKey key: String) -> Any? {
return UserDefaults.standard.value(forKey: key)
}
}
extension DataStorage {
func updateSelected(index: Int?) {
guard let index = index else {
remove(forKey: Keys.selectedIndex.rawValue)
return
}
saveSelected(index: index)
}
var selectedIndex: Int? {
get {
return get(forKey: Keys.selectedIndex.rawValue)
}
set {
guard let index = newValue else {
remove(forKey: Keys.selectedIndex.rawValue)
return
}
saveSelected(index: index)
}
}
}
class SomeLoader {
// MARK: - Public
var dataStorage = DataStorage<Int>()
var selectedIndex: Int? {
get {
return dataStorage.selectedIndex
}
set {
dataStorage.selectedIndex = newValue
}
}
}
let someLoader = SomeLoader()
someLoader.selectedIndex = 1
print(someLoader)
下面的代码适用于任何地方
//: Playground - noun: a place where people can play
import UIKit
struct DataStorage<T: Hashable> {
enum Keys: String {
case selectedIndex
}
private func get<U>(forKey key: String) -> U? {
guard let objectData = getData(forKey: key) else {
return nil
}
let object: U? = get(forData: objectData)
return object
}
private func get<U>(forData objectData: Data) -> U? {
return NSKeyedUnarchiver.unarchiveObject(with: objectData) as? U
}
private func save<U>(forKey key: String, object: U) {
let encodedData = NSKeyedArchiver.archivedData(withRootObject: object)
UserDefaults.standard.set(encodedData, forKey: key)
}
private func remove(forKey key: String) {
UserDefaults.standard.removeObject(forKey: key)
}
private func saveSelected(index: Int) {
save(forKey: Keys.selectedIndex.rawValue, object: index)
}
private func getData(forKey key: String) -> Data? {
return getContent(forKey: key) as? Data
}
private func getContent(forKey key: String) -> Any? {
return UserDefaults.standard.value(forKey: key)
}
}
extension DataStorage {
func updateSelected(index: Int?) {
guard let index = index else {
remove(forKey: Keys.selectedIndex.rawValue)
return
}
saveSelected(index: index)
}
var selectedIndex: Int? {
get {
return get(forKey: Keys.selectedIndex.rawValue)
}
set {
guard let index = newValue else {
remove(forKey: Keys.selectedIndex.rawValue)
return
}
saveSelected(index: index)
}
}
}
class SomeLoader {
// MARK: - Public
var dataStorage = DataStorage<Int>()
var selectedIndex: Int? {
get {
return dataStorage.selectedIndex
}
set {
dataStorage.updateSelected(index: newValue)
}
}
}
let someLoader = SomeLoader()
someLoader.selectedIndex = 1
print(someLoader)
解决方案
推荐阅读
- java - System.out.print 不显示客户数据
- javascript - 等待 serviceWorker 注册不返回激活的工作人员
- mysql - 如何使用“级联”删除用户并自动删除他的所有关系?
- visual-studio-code - VS Code:在顶部和底部面板之间来回切换的键盘快捷键?
- php - 在 php 中使用会话(本地存储)的购物车
- f# - F# SAFE 模板:如何将库添加到服务器?
- python - sqlite 提交不使用 python 更新保存更改?
- angular - 如何从许多延迟加载模块中全局缓存功能模块状态?
- java - 如何在heroku中找到网络服务路径?
- mysql - 为什么 SQL Count(*) 从空表返回 1?