【问题标题】:NsUserDefualts not functioning rightNsUserDefualts 无法正常运行
【发布时间】:2016-01-25 05:35:32
【问题描述】:

基本上我有一些关于 tableView 的错误,我注意到我的 tableView 并不总是正确更新,我尝试调试它,我注意到 tableView 类并不总是被调用来更新表格。我究竟做错了什么 ?当我向表中添加新条目时,计数 4 + 1,我转到历史选项卡,没有任何反应,它显示为计数仍为 4,但如果我再切换选项卡 1 次,它将显示计数为 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)
    }


}

【问题讨论】:

    标签: ios uitableview nsuserdefaults nskeyedarchiver nskeyedunarchiver


    【解决方案1】:

    reloadData 将在您的数组更改时调用,如果您不更改您的数组,或者当您调用 reloadData 但没有数组更新时,没有效果。

    所以基本上,每次你更新数组时,在主队列上调用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()
    })
    

    【讨论】:

    • 我在哪里添加?
    • 您必须检查更新阵列的位置,并将其放在后面。假设现在您的数组计数为 4,当您添加一个新数组时,请在添加后调用 reloadData。对我来说,您听起来不熟悉表格视图的工作原理。尝试找一些教程学习它
    • 所以我注意到如果我添加一个 reloadData 并且只在它正常工作时调用它,那么我如何让它每隔一段时间才工作一次?就像每次用户切换标签时我都可以重置一个标志来运行重新加载数据
    • 调用reloadData取决于你的逻辑,它应该是事件驱动的,只有当数据源更新时,而不是切换视图——当你切换选项卡时,不应该重新加载表视图以提高性能;只有当用户在您的数组中添加一个新条目时,您才应该调用它。调用reloadData 只会告诉表格视图触发 dataSource 委托方法并更新单元格及其布局,仅此而已。
    【解决方案2】:

    有几点:

    1. 将您的数据存储到用户默认值后,调用一次synchronize,以便将更改保存到永久存储中。

    2. 不要将表格视图的每一行的默认值设置为红色 (tableView(_: cellForRowAtIndexPath:))。相反,读取它们一次并将数据存储在数组/字典属性中,并使用它来按需配置每个单元格。

    关于建议 #2:我不认为读取用户的默认值太慢,但我不确定您的存档数据有多大,并且该方法会为表格视图需要在屏幕上显示的每一行调用.高效!

    【讨论】:

      猜你喜欢
      • 2021-04-22
      • 2015-12-08
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多