Ios NsUserDefualts功能不正常

Ios NsUserDefualts功能不正常,ios,uitableview,nsuserdefaults,nskeyedarchiver,nskeyedunarchiver,Ios,Uitableview,Nsuserdefaults,Nskeyedarchiver,Nskeyedunarchiver,基本上,我对tableView有一些bug,我注意到我的tableView并不总是得到正确的更新,我试着调试它,我注意到tableView类并不总是被调用来更新表。我做错了什么?当我向表中添加新条目时,计数4+1,我转到“历史记录”选项卡,但什么也没有发生,它显示为计数仍然为4,但如果我再切换一次选项卡,它将显示计数为5,tableView将被更新。。因此,由于某些原因,更新延迟,我可以添加一个刷新按钮,但我不想这样做 // // SecondViewController.swift // /

基本上,我对tableView有一些bug,我注意到我的tableView并不总是得到正确的更新,我试着调试它,我注意到tableView类并不总是被调用来更新表。我做错了什么?当我向表中添加新条目时,计数4+1,我转到“历史记录”选项卡,但什么也没有发生,它显示为计数仍然为4,但如果我再切换一次选项卡,它将显示计数为5,tableView将被更新。。因此,由于某些原因,更新延迟,我可以添加一个刷新按钮,但我不想这样做

//
//  SecondViewController.swift
//
//  Created by Artiom Sobol on 1/3/16.
//  Copyright © 2016 Artiom Sobol. All rights reserved.
//

import UIKit

class History: UIViewController, UITableViewDataSource, UITableViewDelegate
{
    // test variable
    var test: MyHistory!
    // array to store unarchived history
    var newHistory = [MyHistory]()

    //outlet for tableview

    @IBOutlet var tableView: UITableView!


    override func viewDidLoad()
    {
        //change the background
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: "newBackground.jpg")!)
        super.viewDidLoad()

        //self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "historyCell")
        //unarchive any new data
        let defaults = NSUserDefaults.standardUserDefaults()

        if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
            newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
        }
        tableView.delegate = self
        tableView.dataSource = self
        tableView.reloadData()
    }



    func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int
    {
        return self.newHistory.count
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int
    {
        return 1
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {

        let cell = tableView.dequeueReusableCellWithIdentifier("historyCell", forIndexPath: indexPath) as! historyCell
        let person = newHistory[indexPath.item]
        let defaults2 = NSUserDefaults.standardUserDefaults()

        print("This is count", newHistory.count)

        if let savedPeople = defaults2.objectForKey("MyHistory") as? NSData {
            newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
        }



       // cell.durationLabel.text = String(person.durationNumber)
        let (hour,minutes,seconds) = secondsToHoursMinutesSeconds(person.durationNumber)

        if(seconds < 10 && minutes < 10)
        {
            cell.durationLabel.text = "0\(hour):0\(minutes):0\(seconds)"
        }
        else if(seconds > 9 && minutes < 10)
        {
            cell.durationLabel.text = "0\(hour):0\(minutes):\(seconds)"
        }
        else if(seconds > 9 && minutes > 9)
        {
            cell.durationLabel.text = "0\(hour):\(minutes):\(seconds)"
        }
        else if(seconds < 10 && minutes > 9)
        {
            cell.durationLabel.text = "0\(hour):\(minutes):0\(seconds)"
        }


        cell.kicksLabel.text = String(person.kicksNumber)

        return cell
    }


    func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int)
    {
        return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
    }


}
//
//斯威夫特
//
//由Artiom Sobol于2016年1月3日创建。
//版权所有©2016 Artiom Sobol。版权所有。
//
导入UIKit
类历史记录:UIViewController、UITableViewDataSource、UITableViewDelegate
{
//测试变量
var测试:MyHistory!
//用于存储未归档历史记录的数组
var newHistory=[MyHistory]()
//tableview的出口
@IBVAR表格视图:UITableView!
重写func viewDidLoad()
{
//改变背景
self.view.backgroundColor=UIColor(patternImage:UIImage(名为:“newBackground.jpg”)!)
super.viewDidLoad()
//self.tableView.registerClass(UITableViewCell.self,强制重用标识符:“historyCell”)
//取消归档任何新数据
让defaults=NSUserDefaults.standardUserDefaults()
如果让savedPeople=defaults.objectForKey(“MyHistory”)作为NSData{
newHistory=NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople)为![MyHistory]
}
tableView.delegate=self
tableView.dataSource=self
tableView.reloadData()
}
func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int
{
返回self.newHistory.count
}
func numberOfSectionsInTableView(tableView:UITableView)->Int
{
返回1
}
func tableView(tableView:UITableView,cellForRowAtIndexPath:nsindepath)->UITableView单元格
{
让cell=tableView.dequeueReusableCellWithIdentifier(“historyCell”,forIndexPath:indexPath)作为!historyCell
让person=newHistory[indexPath.item]
让defaults2=NSUserDefaults.standardUserDefaults()
打印(“这是count”,newHistory.count)
如果让savedPeople=defaults2.objectForKey(“MyHistory”)作为NSData{
newHistory=NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople)为![MyHistory]
}
//cell.durationLabel.text=字符串(person.durationNumber)
let(小时、分钟、秒)=秒到小时分钟秒(person.durationNumber)
如果(秒<10和分钟<10)
{
cell.durationLabel.text=“0\(小时):0\(分钟):0\(秒)”
}
否则,如果(秒>9和分钟<10)
{
cell.durationLabel.text=“0\(小时):0\(分钟):\(秒)”
}
否则如果(秒>9和分钟>9)
{
cell.durationLabel.text=“0\(小时):\(分钟):\(秒)”
}
否则,如果(秒<10和分钟>9)
{
cell.durationLabel.text=“0\(小时):\(分钟):0\(秒)”
}
cell.kicklabel.text=字符串(person.kicknumber)
返回单元
}
func secondstohoursminuteseconds(秒:Int)->(Int,Int,Int)
{
返回(秒/3600,(秒%3600)/60,(秒%3600)%60)
}
}

当数组更改时,如果您不更改数组,或者当您调用
重新加载数据
但没有数组更新,没有效果时,将调用重新加载数据

所以,基本上,每次更新数组时,在主队列上调用
reloadData
(如果您的数组更新在另一个队列中,这是必须的)

因此,关于守则:

    if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
        newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
    }
    tableView.delegate = self
    tableView.dataSource = self
    tableView.reloadData()
您只能在
viewDidLoad
中调用
reloadData()
,加载视图控制器时只调用一次

您可以执行以下操作:

self.newHistory = getUpdated()

dispatch_async(dispatch_get_main_queue(), {
    self.tableView.reloadData()
})
有几件事:

  • 在以用户默认值存储数据后,请调用
    同步
    ,以便将更改保存到永久存储

  • 不要红显表视图中每一行的默认值(
    tableView(\uxCELLFORROWATINDEXPATH:)
    )。相反,只需读取一次,并将数据存储在数组/字典属性中,然后使用该属性按需配置每个单元格


  • 关于建议#2:我不认为读取用户默认值的速度太慢,但我不确定归档数据有多大,并且对于表视图需要在屏幕上显示的每一行都会调用该方法。要有效率

    我应该在哪里添加它?你必须检查你在哪里更新你的数组,然后把它放在后面。假设现在您的数组计数为4,当您添加一个新数组时,请在添加后调用reloadData。在我看来,您似乎不熟悉表视图的工作方式。试着找一些学习它的教程,我注意到如果我添加了一个重载数据,并且只调用一次它就可以了,那么如何使它每隔一段时间才工作一次呢?就像每次用户切换选项卡一样,我可以重置一个标志来运行重新加载数据调用
    reloadData
    取决于您的逻辑,它应该是事件驱动的,只有在数据源更新时,而不是切换视图-当您切换选项卡时,不应该重新加载表视图以提高性能;只有当用户在数组中添加新条目时,才应该调用它。调用
    reloadData
    只告诉表视图触发dataSource委托方法并更新单元格及其布局,其他什么都没有。