【问题标题】:iOS: Core Data fails to save when attribute is a doubleiOS:当属性为双精度时,Core Data 无法保存
【发布时间】:2016-03-02 21:41:27
【问题描述】:

我想在我的笔记本电脑飞出窗外之前先在这里问一下。我对 iOS 开发非常陌生,并且一直在玩弄 Core Data 试图创建一个费用管理器应用程序。我有一个名为“Account”的实体,它有两个非可选属性(名称和 initBalance),如下所示:

我还创建了一个 NSManagedObject 子类,如下所示:

//Account.swift

class Account: NSManagedObject {

    override func awakeFromInsert() {
        super.awakeFromInsert()
        initBalance = NSNumber(double: 0.0)
        name = ""
    }    
}

//Account+CoreDataProperties.swift

extension Account {

    @NSManaged var initBalance: NSNumber
    @NSManaged var name: String
}

Account 实体使用 NSFetchedResultsController 呈现在 AccountsViewController(符合 NSFetchedResultsControllerDelegate 协议的 UITableViewController 的子类)中。要添加一个新帐户,我使用来自 AccountsViewController 的 segue 将我定向到具有两个文本字段的 AccountInfoViewController(如下所示),一个用于名称,一个用于帐户余额。当后者即将消失时,将在上下文中插入一个新帐户,其名称和余额来自文本字段。一旦父控制器 (AccountsViewController) 出现,它就会尝试保存更改并更新 tableView。

现在,如果我插入一个余额为整数的新帐户,生活会很好;上下文能够保存更改,tableView 通过显示新插入的帐户来更新其行,我很高兴。当我尝试插入余额为十进制数字的帐户时,应用程序在上下文尝试保存更改的位置崩溃。至于为什么会发生,我根本没有得到任何有用的错误。这是控制器管理文本字段的代码:

class AccountInfoViewController: UIViewController {

    @IBOutlet weak var nameField: UITextField!
    @IBOutlet weak var balanceField: UITextField!

    var store: DataStore! // set by the parent viewController everytime this controller appears

    let numberFormatter = MyFormatter()


    // insert the new account into the context before the controller disappears
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

        store.insertAccount(nameField.text!, balance: numberFormatter.numberFromString(balanceField.text!)!)
    }
}

MyFormatter 是这样的:

func MyFormatter() -> NSNumberFormatter {
    let formatter = NSNumberFormatter()
    formatter.numberStyle = .DecimalStyle
    formatter.minimumFractionDigits = 2
    formatter.maximumFractionDigits = 2
    return formatter    
}

上面显示的 DataStore 包含一个简单的 Core Data Stack 并负责插入到上下文中:

// DataStore.swift

class DataStore {

    let coreDataStack = CoreDataStack(modelName: "SmartMoney")

    // inserts a new account into the context
    func insertAccount(name: String, balance: NSNumber) -> Account {
        let account = NSEntityDescription.insertNewObjectForEntityForName("Account",
            inManagedObjectContext: coreDataStack.mainQueueContext) as! Account

        account.name = name
        account.initBalance = balance
        return account
    }
}

当 balanceField 包含非整数时,上下文无法保存更改是否有任何原因?感谢您阅读,如果您希望我发布代码的任何其他部分,请告诉我。

【问题讨论】:

  • 什么是MyFormatter?您是否确认它不会返回垃圾邮件?
  • @TomHarrington:我在上面添加了 MyFormatter 代码。是的,我已经验证过了,但没有包含在上面显示的代码中。
  • 在退回之前您是否打印了account.initBalance
  • @sschale:刚刚试过,它打印出正确的十进制值。但是,一旦它尝试保存上下文,它就会崩溃....
  • 哦,既然你在赚钱,你真的应该在你的数据模型中使用小数,并使用与它们相关的方法来存储金额。这可能会解决您的问题以及只是实施它们。

标签: ios swift core-data crash nsnumber


【解决方案1】:

我终于能够弄清楚发生了什么。将我的属性名称从 initBalance 更改为 startingBalance 会使一切恢复正常。事实上,将属性名称更改为不以newinit 开头的任何名称都可以正常工作。我从这个post.得到了这个想法

似乎在使用 ARC 时,您的属性名称不应以单词 new 开头。事实证明,initBalance(或newBalance)产生了同样的问题。希望它可以帮助下一个遇到类似问题的可怜的灵魂。

【讨论】:

  • 很奇怪,它只对非整数值崩溃。干得好。
  • 当我的核心数据实体中有一个名为“logID”的 int 16 值时,我遇到了类似的问题。我可以通过将“logID”重命名为“logId”来修复它。我仍然无法弄清楚这有多重要,但您的回答有助于解决崩溃
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多