基本上每当我关闭并重新打开应用程序时,它会在我打开“历史记录”选项卡时崩溃。我很确定它是因为我如何使用NSUserDefaults。谁能引导我通过?
我注意到有时它会在重新打开后打开“历史记录”选项卡但是如果我向Nsuserdefaults添加一个新条目它会崩溃,在我重新打开它之后它会正常工作并显示上一个条目或它将删除所有内容并保持仅限新条目。
//
// SecondViewController.swift
// Angelina
//
// 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
let defaults = NSUserDefaults.standardUserDefaults()
@IBOutlet var tableView: UITableView!
override func viewDidLoad()
{
//change the 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 is 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)
}
}
我想我刚才意识到应用关闭后我的数组会重新启动。这就是为什么桌子崩溃了,它越界了..
这是我保存数组的另一个文件。
import UIKit
class Kicks: UIViewController
{
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!
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()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "background13.png")!)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be 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, 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)
}
}
答案 0 :(得分:1)
它清楚地说:
'NSRangeException',原因:'*** - [__ NSArrayI objectAtIndex:]:索引1超出界限[0 .. 0]'
仔细检查数组对象,例如newHistory
在应用启动时包含所有元素
似乎
func tableView(tableView: UITableView,numberOfRowsInSection section: Int) -> Int
{
return self.newHistory.count
}
self.newHistory.count不为0因此会触发cellForRowAtIndexPath
,尝试在numberOfRowsInSection
和cellForRowAtIndexPath
内添加两个断点,这样您就可以知道出了什么问题。通常,如果没有数据,numberOfRowsInSection
将返回0并且cellForRowAtIndexPath
将不会被触发。
您还可以在Xcode BreakPoint导航器中使用异常点,这样您就可以在任何异常时中断。这是您需要掌握的简单调试技巧。