【问题标题】:App crashes when checking array length检查数组长度时应用程序崩溃
【发布时间】:2014-10-19 21:13:51
【问题描述】:

一段时间以来,我的应用程序的某个特定部分一直存在问题,我认为它已修复,但我刚刚注意到它似乎仍在崩溃。

基本上,我有一个数组来存储用户可以用来节省时间的预设名称。如果用户使用的名称不是预设名称,则会将其添加到预设列表中。如果他们使用预先存在的预设,则将其移至列表顶部。预设列表一次限制为 15 个。

问题是,当我点击与包含所有预设的表格视图的视图控制器相连的按钮时,应用程序崩溃。

我这样声明数组:

var presetNamesMutable: NSMutableArray = ["Shopping", "Holiday", "Christmas", "Groceries", "Weekend Away", "Birthday", "Wedding", "Day Out", "Savings", "Party"]
var presetNames: NSArray = []

这是预设视图控制器中的代码:

override func viewWillAppear(animated: Bool) {
        presetNames = NSUserDefaults.standardUserDefaults().objectForKey("presets") as NSArray
        presetNamesMutable = presetNames.mutableCopy() as NSMutableArray
        println(presetNamesMutable)

        while presetNamesMutable.count > 15 {
            presetNamesMutable.removeLastObject()
            NSUserDefaults.standardUserDefaults().setObject(presetNamesMutable, forKey: "presets")
        }
} 

这是视图控制器中处理添加/移动名称的代码:

    if presetNamesMutable.containsObject(budgetName) == false && budgetName != "Budget" {
        presetNamesMutable.insertObject(budgetName, atIndex: 0)
        NSUserDefaults.standardUserDefaults().setObject(presetNamesMutable, forKey: "presets")
    } else if presetNamesMutable.containsObject(budgetName) == true && budgetName != "Budget" {
        var indexValue = presetNamesMutable.indexOfObject(budgetName)
        presetNamesMutable.removeObjectAtIndex(indexValue)
        presetNamesMutable.insertObject(budgetName, atIndex: 0)
        NSUserDefaults.standardUserDefaults().setObject(presetNamesMutable, forKey: "presets")
    }

应用崩溃:

        while presetNamesMutable.count > 15 {

有人有什么想法吗?

【问题讨论】:

  • 崩溃时的实际错误消息是什么? println() 是否显示数组内容?你可以登录presetNamesMutable.count 吗?不确定您的变量声明。在 Swift 中,varlet 的使用会为您处理可变性,因此尝试将 var presetNames: NSArray = [] 用作不可变数组是不正确的。将已经可变数组的 mutableCopy 显式向下转换为 NSMutableArray 似乎是多余的。
  • 我刚收到EXC_BAD_INSTRUCTION。 println() 似乎不显示数组内容。我尝试注释掉 while 循环,但应用程序仍然崩溃,所以我想它一定是 mutableCopy。我有一个可变副本的原因是因为使用 NSUserDefaults 存储数组会使数组不可变,如果我是正确的?
  • @mc01 令人惊讶的是,如果用户从未手动输入名称,应用程序只会崩溃。所以基本上,如果他们在第一次启动应用程序时尝试使用预设名称,那么它就会崩溃。但第一次使用后一切正常......
  • 如果println() 没有显示任何内容,那么它会在那里崩溃而不是在while 循环中,这意味着presetNamesMutable 可能不是您所期望的。我建议删除 as NSArrayas NSMutableArray downcasts & println 每个结果。如果它们是 nil 并且您使用 as 进行向下转换,它会解开可选值并期望一个非零值。最初的崩溃可能是由于nil 数组造成的吗?此外,您存储在 NSUserDefaults 中的任何内容都应该是不可变的——这就是它的目的。您获取存储的内容并使用本地可变副本,直到再次保存为止。
  • 听起来不错。当我明天有更多时间时,我会尝试一下。我已经发布了我现在正在使用的临时修复程序。感谢您的帮助!

标签: ios swift nsmutablearray


【解决方案1】:

作为临时修复,我将代码更改为:

    if NSUserDefaults.standardUserDefaults().boolForKey("presetsAvailable") == true {
        presetNames = NSUserDefaults.standardUserDefaults().objectForKey("presets") as NSArray
        presetNamesMutable = presetNames.mutableCopy() as NSMutableArray
        println(presetNamesMutable.count)

        while presetNamesMutable.count > 15 {
            presetNamesMutable.removeLastObject()
            NSUserDefaults.standardUserDefaults().setObject(presetNamesMutable, forKey: "presets")
        }
    }

基本上,当用户第一次使用该应用时,它会崩溃。所以我现在已经做到了,让应用程序崩溃的代码在用户至少使用一次应用程序之前不会被执行。

【讨论】:

    【解决方案2】:

    我编写了一个带有一些 println() 语句的 swift 版本来检查准确性。我将数组限制为 10 个值,因为这是提供的列表,我不想在假期时太有创意。 :-) 将其粘贴到操场上:

    var presets = ["Shopping", "Holiday", "Christmas", "Groceries", "Weekend Away", "Birthday", "Wedding", "Day Out", "Savings", "Party"]
    
    println(presets)
    
    let name = "Shazam"
    
    func isPreset() {
        if contains(presets, name) {
            println("presets contains \(name)")
        } else {
            presets.insert(name, atIndex: 0)
            println("added \(name) at index 0 of presets")
        }
    
        while presets.count > 10 {
            println("removed \(presets[presets.count-1]) from presets")
            presets.removeLast()
        }
    }
    
    isPreset()
    println(presets)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-19
      • 2015-02-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-11
      • 2016-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多