basically every time close , reopen app crashes when open history tab. im pretty sure because of how use nsuserdefaults. can guide me through?
what noticed opens history tab after reopening if add new entry nsuserdefaults crash, after reopen it work fine , show previous entry or remove , keep new entry only.
// // secondviewcontroller.swift // angelina // // created artiom sobol on 1/3/16. // copyright © 2016 artiom sobol. rights reserved. // import uikit class history: uiviewcontroller, uitableviewdatasource, uitableviewdelegate { // test variable var test: myhistory! // array store unarchived history var newhistory = [myhistory]() //outlet tableview let defaults = nsuserdefaults.standarduserdefaults() @iboutlet var tableview: uitableview! override func viewdidload() { //change background self.view.backgroundcolor = uicolor(patternimage: uiimage(named: "newbackground.jpg")!) super.viewdidload() if let savedpeople = defaults.objectforkey("myhistory") as? nsdata { newhistory = nskeyedunarchiver.unarchiveobjectwithdata(savedpeople) as! [myhistory] } tableview.delegate = self tableview.datasource = self } override func viewdidappear(animated: bool) { super.viewdidappear(animated) 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 count", newhistory.count) // if let savedpeople = defaults.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) } }
i think realized array gets restarted after app turned off. thats why table crashes cus goes out of bounds..
this other file saving of array happens.
import uikit class kicks: uiviewcontroller { var count = 0 int var countkicks = 0 int var kickreached = false bool var pressedonce = true bool var timer = nstimer() var test: myhistory! var datestring = " " @iboutlet var timerlabel: uitextfield! @iboutlet var kickslabel: uitextfield! @iboutlet var datedisplay: uitextfield! @iboutlet var kickbutton: uibutton! var myhistoryarray: [myhistory] = [] var currentmyhistory: myhistory! override func viewdidload() { super.viewdidload() self.printtimestamp() // additional setup after loading view, typically nib. self.view.backgroundcolor = uicolor(patternimage: uiimage(named: "background13.png")!) } override func didreceivememorywarning() { super.didreceivememorywarning() // dispose of resources can recreated. } @ibaction func kickbutton() { //currentmyhistory.kicksnumber = 5 kickbutton.setimage(uiimage(named: "gold-button-heart-icon.png"), forstate: uicontrolstate.normal) if(pressedonce == true) { pressedonce = false timer = nstimer.scheduledtimerwithtimeinterval(1, target: self, selector: selector("counter"), userinfo: nil, repeats: true) } else if(kickreached == true) { // let date = nsdate() // let calendar = nscalendar.currentcalendar() // let timer_total = calendar.components([ .hour, .minute, .second], fromdate: date) } else if(pressedonce == false) { countkicks++ kickslabel.text = "\(countkicks)" if(countkicks == 10) { self.printtimestamp() kickreached = true timer.invalidate() kickbutton.setimage(uiimage(named: "pink-button-heart-icon.png"), forstate: uicontrolstate.normal) congratsalert() currentmyhistory = myhistory(kicksnumber: countkicks, durationnumber: count) myhistoryarray.append(currentmyhistory) test = myhistoryarray[0] print("countof array ", myhistoryarray.count) printtimestamp() // prints "sep 9, 2014, 4:30 am" //save data let saveddata = nskeyedarchiver.archiveddatawithrootobject(myhistoryarray) let defaults = nsuserdefaults.standarduserdefaults() defaults.setobject(saveddata, forkey: "myhistory") clear() } } } func printtimestamp() { let timestamp = nsdateformatter.localizedstringfromdate(nsdate(), datestyle: .mediumstyle, timestyle: .shortstyle) print(timestamp) datedisplay.text = "\(timestamp)" } // save countkicks, count, , stamp func congratsalert() { let alert = uialertcontroller(title: "congratulation", message: "yay!!! angelina kicked 10 times in less 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) } }
it says clearly:
'nsrangeexception', reason: '*** -[__nsarrayi objectatindex:]: index 1 beyond bounds [0 .. 0]'
double check array objects newhistory
has elements when app starts
it seems
func tableview(tableview: uitableview,numberofrowsinsection section: int) -> int { return self.newhistory.count }
self.newhistory.count not 0 trigger cellforrowatindexpath
, try add 2 break points inside numberofrowsinsection
, cellforrowatindexpath
, can know what's goes wrong. usually, if no data, numberofrowsinsection
return 0 , cellforrowatindexpath
not triggered.
you can exception point in xcode breakpoint navigator, can break @ exceptions. simple debug skills need master.
Comments
Post a Comment