NsUserDefualts无法正常运行

时间:2016-01-25 05:35:32

标签: ios uitableview nsuserdefaults nskeyedarchiver nskeyedunarchiver

基本上我有一些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)
    }


}

2 个答案:

答案 0 :(得分:0)

在更改阵列时调用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()

您只在reloadData()中调用viewDidLoad,只在视图控制器加载时调用一次。{/ p>

您可以执行以下操作:

self.newHistory = getUpdated()

dispatch_async(dispatch_get_main_queue(), {
    self.tableView.reloadData()
})

答案 1 :(得分:0)

有几件事:

  1. 将数据存储在用户默认值后,请拨打using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ClientSocket { public class Program { static void Main(string[] args) { TcpClient clientSocket = new TcpClient(); clientSocket.Connect(destinationPort, destinationPort); //((System.Net.IPEndPoint)(clientSocket.Client.LocalEndPoint)).Port = 3389; I want to fix my port in advance something like this or any other way Console.WriteLine(" >> Client Started"); while (true) { try { NetworkStream serverStream = clientSocket.GetStream(); byte[] outStream = System.Text.Encoding.ASCII.GetBytes("" + "$"); Console.WriteLine("\nPing to Server:"); serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); byte[] inStream = new byte[10025]; serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize); string returndata = System.Text.Encoding.ASCII.GetString(inStream); Console.WriteLine("Reply from server:" + returndata); Thread.Sleep(5000); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } } } 一次,以便将更改保存到永久存储空间。

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

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