在更新中添加新数组的问题

时间:2014-10-31 23:08:45

标签: ios swift nsuserdefaults

我的应用程序的更新现已准备就绪,但是我注意到直接从应用程序商店的应用程序版本更新到我在Xcode中工作的新版本似乎会导致我的应用程序崩溃。 / p>

基本上,我添加了一个新数组,用于存储以前版本中不存在的笔记数据,这些数据存储在NSUserDefaults中(不太理想,我知道,但我现在宁愿保持这种方式)

当我进入我的应用程序的表格视图标签时,它会在此行崩溃:

cell.notesLabel.text = (notes.objectAtIndex(indexPath.row)) as? String

错误只是说明了 - "线程1:断点1.1"只要点击表格视图选项卡。

我正在与其他人讨论这个问题,他们建议我需要检查默认值中是否存在数组,如果缺少则创建并同步它。

我不完全确定如何解决此问题,但我尝试更改此代码:

if var tempNotes: NSArray = NSUserDefaults.standardUserDefaults().arrayForKey("notes") {
    notes = tempNotes.mutableCopy() as NSMutableArray
}

对此:

if NSUserDefaults.standardUserDefaults().arrayForKey("notes") != nil {
    var tempNotes: NSArray = NSUserDefaults.standardUserDefaults().arrayForKey("notes")!
    notes = tempNotes.mutableCopy() as NSMutableArray
}

然而,它似乎并没有起到什么作用。顺便说一句,该代码在viewWillAppear()中。

有什么想法吗?

编辑:

didSelectRowAtIndexPath()numberOfRowsInSection()代码:

override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete method implementation.
    // Return the number of rows in the section.

    if tableView == self.searchDisplayController?.searchResultsTableView {
        return searchResults.count
    } else {
    if names.count == 0 {
        if enterButtonTapped == false {
            backgroundLabel.text = "Before you add any transactions, you must first set a budget. You can do this by tapping the 'Budget' tab."
        } else {
            backgroundLabel.text = "You haven't added any transactions yet. Tap the add button to add a new transaction."
        }
        backgroundLabel.frame = CGRectMake(0, 0, self.view.bounds.width, self.view.bounds.height)
        backgroundLabel.numberOfLines = 0
        backgroundLabel.textAlignment = NSTextAlignment.Center
        backgroundLabel.sizeToFit()
        backgroundLabel.hidden = false
        backgroundLabel.font = UIFont(name: "Avenir", size: 17)
        backgroundLabel.textColor = UIColor.lightGrayColor()

        clearButton.enabled = false

        self.tableView.backgroundView = backgroundLabel
        self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        self.tableView.scrollEnabled = false
        return 0
    } else {
        backgroundLabel.hidden = true
        self.tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
        self.tableView.scrollEnabled = true
        clearButton.enabled = true
        return names.count
    }
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell:CustomTransactionTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomTransactionTableViewCell

    var arrowX: CGFloat = 0
    var amountX: CGFloat = 0
    if height == 480 || height == 568 {
        arrowX = 260
        amountX = 152
    } else if height == 667 {
        arrowX = 315
        amountX = 217
    } else {
        arrowX = 354
        amountX = 217
    }

    cell.notesLabel.alpha = 0
    cell.paymentNameLabel.frame.origin.x = 20
    cell.dateLabel.frame.origin.x = 20
    cell.costLabel.frame.origin.x = amountX
    cell.creditArrowImage.frame.origin.x = arrowX
    cell.paymentArrowImage.frame.origin.x = arrowX

    cell.selectionStyle = UITableViewCellSelectionStyle.None

    if tableView == self.searchDisplayController?.searchResultsTableView {
        cell.paymentNameLabel.text = (searchResults.objectAtIndex(indexPath.row)) as? String
        var indexValue = names.indexOfObject(searchResults.objectAtIndex(indexPath.row))
        cell.costLabel.text = (values.objectAtIndex(indexValue)) as? String
        cell.dateLabel.text = (dates.objectAtIndex(indexValue)) as? String
        cell.notesLabel.text = (notes.objectAtIndex(indexValue)) as? String

        if images.objectAtIndex(indexValue) as NSObject == 0 {
            cell.paymentArrowImage.hidden = false
            cell.creditArrowImage.hidden = true
        } else if images.objectAtIndex(indexValue) as NSObject == 1 {
            cell.creditArrowImage.hidden = false
            cell.paymentArrowImage.hidden = true
        }

        if notes.objectAtIndex(indexValue) as NSString == "" {
            cell.notesLabel.text = "No notes to display."
        }

        //This works, unless there are two payments with the same name. To revert to previous version, remove tableView if statement and just keep code below the else.
    } else {
        cell.paymentNameLabel.text = (names.objectAtIndex(indexPath.row)) as? String
        cell.costLabel.text = (values.objectAtIndex(indexPath.row)) as? String
        cell.dateLabel.text = (dates.objectAtIndex(indexPath.row)) as? String
        cell.notesLabel.text = (notes.objectAtIndex(indexPath.row)) as? String

        if images.objectAtIndex(indexPath.row) as NSObject == 0 {
            cell.paymentArrowImage.hidden = false
            cell.creditArrowImage.hidden = true
        } else if images.objectAtIndex(indexPath.row) as NSObject == 1 {
            cell.creditArrowImage.hidden = false
            cell.paymentArrowImage.hidden = true
        }

        if notes.objectAtIndex(indexPath.row) as NSString == "" {
            cell.notesLabel.text = "No notes to display."
        }
    }
    return cell
}

1 个答案:

答案 0 :(得分:1)

快速浏览表明,有一个复杂的逻辑决定在numberOfRows中返回多少行,然后是复杂的 - 而且是不同的 - 基于cellForRow中的indexPath访问数组的逻辑。在我们解决用户默认问题之前 - 代码是崩溃的秘诀。这两种方法的正确形式是将它们紧密地相互对应:

  • 在numbeOfRows中,确定您要回答计数的数组 对于。那是你的模特。
  • 在cellForRow中,取消引用相同的数组 使用indexPath.row。你永远不会有一个超出范围的索引 因为如果你为numberOfRows回答N(其中 N = someArray.count),然后只用行调用cellForRow 0..N-1

在用户默认问题上:您的新应用版本必须准备好处理旧版本留下的任何用户默认状态,包括缺席,对于从未拥有旧版本的用户。为了防弹,请始终通过方法获取默认值。它应该在默认情况下查找数组。如果找到,则将可变副本缓存为实例变量并将其返回。否则,如果未找到(您发布的测试代码arrayForKey("notes") != nil与未找到相反),请将实例var初始化为新数组并返回该数组。