NSUserDefaults无法在Swift中使用UITableView

我对Swift比较新,我正在做一个基本的家庭作业日记应用程序。 到目前为止,我所拥有的是一个嵌入在导航控制器中的UITableView,它嵌入在标签栏控制器中。 我已成功设法实现拉动刷新,在UIAlertView中添加数据并在刷新后用这些数据填充表格。 我需要这个应用程序的持久数据,我听说NSUserDefaults是最好的方法,但它不适合我。 我可以看到它正在添加到NSUserDefaults,但在我关闭并重新打开应用程序后,它似乎没有再出现在UITableView中。 有什么建议么? 我的代码如下。 此外,要将这些数据放到网上,有没有办法使用Google表格作为我的应用程序的在线数据库?

import UIKit var classesData = [String]() var teachersData = [String]() let defaults = NSUserDefaults.standardUserDefaults() var tableData1 = defaults.valueForKey("classesData") as! NSArray var tableData2 = defaults.valueForKey("teachersData") as! NSArray class ClassesList: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate { lazy var refreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged) return refreshControl }() @IBOutlet weak var tableView: UITableView! @IBAction func addClass(sender: AnyObject) { var subjectTextField: UITextField? var teacherTextField: UITextField? let alertController = UIAlertController(title: "Add Class", message: "Please input the name of the subject and the teaceher", preferredStyle: .Alert) let done = UIAlertAction(title: "Done", style: .Default, handler: { (action) -> Void in classesData.append(subjectTextField!.text!) teachersData.append(teacherTextField!.text!) print(classesData) print(teachersData) }) let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in } alertController.addAction(done) alertController.addAction(cancel) alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. subjectTextField = textField subjectTextField?.placeholder = "Subject" } alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. teacherTextField = textField teacherTextField?.placeholder = "Teacher" } presentViewController(alertController, animated: true, completion: nil) } override func viewDidLoad() { super.viewDidLoad() self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "classCell") self.tableView.addSubview(self.refreshControl) // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func handleRefresh(refreshControl: UIRefreshControl) { defaults.setValue(classesData, forKey: "classesData") defaults.setValue(teachersData, forKey: "teachersData") print(tableData1) defaults.synchronize() self.tableView.reloadData() refreshControl.endRefreshing() } func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return classesData.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("classCell")! as UITableViewCell cell.textLabel?.text = (tableData1[indexPath.row] as? String)! + " , " + (tableData2[indexPath.row] as? String)! return cell } } 

在启动时,您使用tableData1和tableData2来存储默认值的信息,但classesData和teachersData初始化为空。 当应用程序启动时,它调用numberOfRowsInSection并返回classesData.count,该值为零。 您遇到的另一个问题是,您的应用程序将在第一次运行时崩溃,因为您使用空的NSUserDefaults数据初始化它。 重置iOS模拟器,然后运行您的应用程序,它将崩溃。 你需要检查和处理来自NSUserDefaults的空数据,这里介绍了如何在swift中保存和读取NSUserdefaults中的数组数组?

我建议如下:1)删除tableData1和tableData1并用appData中的classesData和teachersData替换。 2)创建一个名为loadUserDefaults()的新函数,该函数在viewDidLoad中调用,该函数在检查空的NSUserDefaults数据时从NSUserDefaults加载数据。 3)在handleRefresh()中只保存数据,重新加载表视图并结束刷新。 有了这些建议,工作代码如下。

 import UIKit var classesData = [String]() var teachersData = [String]() let defaults = NSUserDefaults.standardUserDefaults() class ClassesList: UIViewController, UITableViewDelegate, UITableViewDataSource, UIPopoverPresentationControllerDelegate { lazy var refreshControl: UIRefreshControl = { let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged) return refreshControl }() @IBOutlet weak var tableView: UITableView! @IBAction func addClass(sender: AnyObject) { var subjectTextField: UITextField? var teacherTextField: UITextField? let alertController = UIAlertController(title: "Add Class", message: "Please input the name of the subject and the teaceher", preferredStyle: .Alert) let done = UIAlertAction(title: "Done", style: .Default, handler: { (action) -> Void in classesData.append(subjectTextField!.text!) teachersData.append(teacherTextField!.text!) }) let cancel = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in } alertController.addAction(done) alertController.addAction(cancel) alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. subjectTextField = textField subjectTextField?.placeholder = "Subject" } alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in // Enter the textfiled customization code here. teacherTextField = textField teacherTextField?.placeholder = "Teacher" } presentViewController(alertController, animated: true, completion: nil) } override func viewDidLoad() { super.viewDidLoad() self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "classCell") self.tableView.addSubview(self.refreshControl) loadUserDefaults() } func handleRefresh(refreshControl: UIRefreshControl) { defaults.setValue(classesData, forKey: "classesData") defaults.setValue(teachersData, forKey: "teachersData") defaults.synchronize() self.tableView.reloadData() refreshControl.endRefreshing() } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return classesData.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("classCell")! as UITableViewCell cell.textLabel?.text = (classesData[indexPath.row] as? String)! + " , " + (teachersData[indexPath.row] as? String)! return cell } func loadUserDefaults() { if let tempClassArray = defaults.valueForKey("classesData") { classesData = tempClassArray as! [String] } if let tempTeacherArray = defaults.valueForKey("classesData") { teachersData = tempTeacherArray as! [String] } } }