swift - 将 NSCore 和 NSKeyedArchiver 与 SWIFT 结合使用

标签 swift class nsuserdefaults nscoder

我一直在尝试在我的应用程序上获取持久数据,以获取用户条目的历史记录。将数据存储到数组后,我想将其存档,在取消存档后,我得到奇怪的值,而不是我想看到的值。

这是我存储数据的类

导入基础

class MyHistory: NSObject, NSCoding {
    var kicksNumber: Int
    var durationNumber: Int


     init(kicksNumber: Int,durationNumber: Int) {
        self.kicksNumber = kicksNumber
        self.durationNumber = durationNumber
    }

    required init(coder decoder: NSCoder) {
        kicksNumber = decoder.decodeObjectForKey("kicksNumber") as! Int
        durationNumber = decoder.decodeObjectForKey("durationNumber") as! Int
    }


    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(self.kicksNumber, forKey: "kicksNumber")
        coder.encodeObject(self.durationNumber, forKey: "durationNumber")   
    }
}

然后这是我的类,事情发生的地方,我正在测试保存和加载过程。

class Kicks: UIViewController {

    var myHistoryArray: [MyHistory] = []
    var currentMyHistory: MyHistory!
    var newHistory = [MyHistory]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background13.png")!)


        let defaults = NSUserDefaults.standardUserDefaults()

        if let savedPeople = defaults.objectForKey("MyHistory") as? NSData {
            newHistory = NSKeyedUnarchiver.unarchiveObjectWithData(savedPeople) as! [MyHistory]
            //print("this is archived ", newHistory[0])

        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    var count = 0 as Int
    var countKicks = 0 as Int
    var kickReached = false as Bool
    var pressedOnce = true as Bool
    var timer = NSTimer()
    var test: MyHistory!

    @IBOutlet var timerLabel: UITextField!
    @IBOutlet var kicksLabel: UITextField!


    @IBAction func kickButton() {
        //currentMyHistory.kicksNumber = 5


        if pressedOnce {
            pressedOnce = false
            timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counter"), userInfo: nil, repeats: true)
        } else if kickReached {

            //  let date = NSDate()
            //  let calendar = NSCalendar.currentCalendar()
            // let timer_total = calendar.components([ .Hour, .Minute, .Second], fromDate: date)
        } else if !pressedOnce {
            countKicks++
            kicksLabel.text = "\(countKicks)"
            if countKicks == 10 {
                kickReached = true
                timer.invalidate()
                congratsAlert()

                currentMyHistory = MyHistory(kicksNumber: 5, durationNumber: 10)
                print("this is currentMyHistory", currentMyHistory.kicksNumber )

                myHistoryArray.append(currentMyHistory)
                test = myHistoryArray[0]
                print("this is myHistoryArray0",  test.kicksNumber)
                //save data
                let savedData = NSKeyedArchiver.archivedDataWithRootObject(myHistoryArray)
                let defaults = NSUserDefaults.standardUserDefaults()
                defaults.setObject(savedData, forKey: "MyHistory")
                //load data
                //let defaults = NSUserDefaults.standardUserDefaults()

               // let person = people[indexPath.item]
               //let historyUnarchived = NSKeyedUnarchiver.unarchiveObjectWithFile("/path/to/archive") as? [MyHistory]
         //       let data1 = NSUserDefaults.standardUserDefaults().objectForKey("myHistoryArray")
                print("this is unrachived",newHistory[0])
                clear()
            }
        }
    }

    // save countKicks, count, and stamp i
    func congratsAlert() {
        let alert = UIAlertController(title: "Congratulation", message: "Yay!!! Angelina kicked 10 times in less than 2 hours.",preferredStyle: .Alert)

        let okAction = UIAlertAction(title: "Ok",style: .Default,handler:{(action:UIAlertAction) -> Void in})
        alert.addAction(okAction)

        presentViewController(alert,animated: true,completion: nil)
    }

    func clear() {
        count = 0
        countKicks = 0
        kickReached = false
        pressedOnce = true
        timerLabel.text = "00:00:0\(count)"
        kicksLabel.text = "\(countKicks)"
    }

    func counter() {
        ++count
        let (hour,minutes,seconds) = secondsToHoursMinutesSeconds(count)

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

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

    func savePlaces() {
        let placesArray = [myHistory(kicksNumber: 420, durationNumber: 89)]
        let placesData = NSKeyedArchiver.archivedDataWithRootObject(placesArray)
        NSUserDefaults.standardUserDefaults().setObject(placesData, forKey: "kicks")
    }

    func loadPlaces() {
    let placesData = NSUserDefaults.standardUserDefaults().objectForKey("kicks") as? NSData

    if let placesData = placesData {
    let placesArray = NSKeyedUnarchiver.unarchiveObjectWithData(placesData) as? [myHistory]

    if let placesArray = placesArray {
    // do something…
    }

    }
    }*/
}

我的输出是这样的:

这是当前我的历史 5

这是 myHistoryArray0 5

这是未实现的

来自调试器的消息:由于信号 15 而终止

为什么未归档的值很奇怪?

最佳答案

在您的 MyHistory 类中您使用的是整数,因此在您的encodeWithCoder 函数中您应该使用

coder.encodeInteger(self.kicksNumber, forKey: "kicksNumber")
coder.encodeInteger(self.durationNumber, forKey: "durationNumber") 

同样,对于您的解码器,您应该使用decodeIntForKey,而不是decodeObjectForKey。

kicksNumber = decoder.decodeIntegerForKey("kicksNumber")
durationNumber = decoder.decodeIntegerForKey("durationNumber")

关于swift - 将 NSCore 和 NSKeyedArchiver 与 SWIFT 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34887110/

相关文章:

class - Perl 中的对象属性访问

ios - 无法通过 IOS 中的变量设置 NSUserDefaults 值

swift - 使用 Combine 框架的按钮操作

swift - 如何使用 AVPlayer 进行基本身份验证来播放服务器上的视频文件?

python - 从嵌套字典构建类

swift - Userdefaults Tableview 地标 Swift 3

swift - 如何在不使用临时变量的情况下在 NSUserDefaults 中写入字典条目?

ios - 如何在 UITextView textViewDidBeginEditing 中显示键盘后显示警报

swift - 为什么这个 Swift 代码不进行类型检查?

python - 运行 'classloop'时出错