如何使用全局变量数组实现 userDefaults
Posted
技术标签:
【中文标题】如何使用全局变量数组实现 userDefaults【英文标题】:How to implement userDefaults with a Global Variable array 【发布时间】:2020-05-14 21:35:29 【问题描述】:我有一个空数组设置为全局变量,其中填充了表格视图中的数组项。这用于填充另一个表视图。这些数据需要持久化,以便当用户返回应用程序时,他们的 tableview 数据处于与离开时相同的状态,即使用数组中的数据填充。
虽然我已经寻找了几十个教程和示例。我自己也破解了它以使其工作,每次我重新加载应用程序时,数组都是空的。如何让该全局变量数组保留它的数组数据?
var sharedData = [String]()
这是我的第一个 VC,其中我有 UserDefaults 的设置功能。每次对数组进行更改时,我都会执行我的 saveArray() 函数。每次我需要从数组中加载时,我都会执行 retrieveArray() 函数。
import UIKit
var sharedData = [String]()
struct Keys
static let arrayKey = "arrayKey"
let defaults = UserDefaults.standard
func saveArray()
defaults.set(sharedData, forKey: Keys.arrayKey)
func retrieveArray()
var savedData = defaults.object(forKey: Keys.arrayKey) as? [String] ?? []
savedData.append(contentsOf: sharedData)
class ViewController: UIViewController
var effect:UIVisualEffect!
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet var tableView: UITableView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBOutlet weak var visualEffectView: UIVisualEffectView!
let materialData = ["One", "Two", "Three", "Four"]
var searchMaterial = [String]()
var searching = false
@IBAction func favoritesButtonArrayUpdate(_ sender: UIBarButtonItem)
print(sharedData)
override func viewDidLoad()
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
saveArray()
retrieveArray()
print(sharedData)
extension ViewController: UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
tableView.deselectRow(at: indexPath, animated: true)
print(self.materialData[indexPath.row], "selected!")
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
let favorite = UITableViewRowAction(style: .default, title: "Favorite") (action, indexPath) in
var data: String
if self.searching
data = self.searchMaterial[indexPath.row]
else
data = self.materialData[indexPath.row]
sharedData.append(data)
saveArray()
print(sharedData)
favorite.backgroundColor = UIColor.orange
return [favorite]
这是我的第二个 VC,它显示存储在全局变量数组 sharedData 中的数组数据。在对数组进行更改并从数组中提取数据时,我再次添加了所有 func。
import UIKit
class FavoritesViewController: UIViewController
@IBOutlet var tableView: UITableView!
override func viewDidLoad()
super.viewDidLoad()
saveArray()
retrieveArray()
extension FavoritesViewController: UITableViewDelegate, UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
retrieveArray()
return sharedData.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
retrieveArray()
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.numberOfLines = 0
cell.textLabel?.text = sharedData[indexPath.row]
return cell
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
return true
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)
if editingStyle == .delete
sharedData.remove(at: indexPath.row)
saveArray()
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
【问题讨论】:
【参考方案1】:问题可能出在这里:
let savedData: [String] = userDefaults.object(forKey: "arrayKey") as? [String] ?? []
尝试更改它:
let savedData: [String] = userDefaults?.object(forKey: "arrayKey") as? [String] ?? []
这是因为必须解包 UserDefaults 才能引用成员对象。试试看
【讨论】:
Xcode 响应“不能在 'UserDefaults' 类型的非可选值上使用可选链接”并建议删除添加的“?” 那么原始版本到底有什么问题? (也许用确切的问题更新问题)。 “我需要在重新启动应用程序时恢复阵列中的数据”到底是什么意思,您是否希望它们在重新启动时出现? (“恢复”有点难以理解)。你打算在哪里使用 userDefaults ?也许你应该考虑使用suiteName。查看 Apple 文档 没关系。如果您编写 userDefaults.set(sharedData, forKey: "arrayKey") 您正在使用 sharedData 中的数据填充 userDefaults 的键“arrayKey”,但如果您刚刚启动应用程序,sharedData 是空的,所以如果您尝试,立即之后,用 let savedData: [String] = userDefaults.object(forKey: "arrayKey") 填充 savedDate 它将是空的,因为 userDefaults 中的 "arrayKey" 是空的。因此,当用户输入填充 shareData 时,您需要使用 shareData 在 userdefaults 中填充“arrayKey”,然后在应用启动时,从 userdefaults 填充 savedData(开始时的某处)。 字符不够清晰。我的意思是,您必须在不同的时刻填充 userdefaults 然后填充 savedData 否则如果您刚刚启动应用程序(A = B,B = C,所以 A = C,如果 A = 空,C = 空)。因此,找到将 sharedData 存储在 userDefaults 中的合适时机,以及使用 Userdefaults 内容填充 savedData 的合适时机。如果你有它,也许可以在启动类中做第二件事,或者在启动的场景委托中做第二件事,或者根据你的项目做其他事情。 我把它整理好了。无需套件名称:。我只需要正确处理工作流程。我试图把它复杂化太多。感谢您的帮助!【参考方案2】:根据MrHim 的建议,我从我的第一个VC 的viewDidLoad 中删除了saveArray 和retrieveArray 函数,并将retrieveArray 留在了我的第二个VC 的viewDidLoad 中。在我的 viewDidLoads 中有 saveArray 是用空数据覆盖数组。然后我需要在我的第二个 VC 中的适当位置检索数组数据。然后在我的 numberOfRowsInSection 中,我删除了 retrieveArray。
【讨论】:
以上是关于如何使用全局变量数组实现 userDefaults的主要内容,如果未能解决你的问题,请参考以下文章
在 SwiftUI 中使用 UserDefaults 进行全局更新
如何使用 userDefaults 保存打印数组(swift 3)