2016-03-02 1 views
2

Je pensais que je demanderais ici avant d'envoyer mon ordinateur portable par la fenêtre. Je suis très nouveau dans le développement iOS et je me suis mis à l'aise avec Core Data en essayant de créer une application de gestion des dépenses. J'ai une seule entité nommée "Compte" qui a deux attributs non optionnels (nom et initBalance) comme suit:iOS: Core Data ne parvient pas à enregistrer lorsque l'attribut est un double

enter image description here

J'ai également créé une sous-classe NSManagedObject comme suit:

//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 
} 

Les entités de compte sont présentées dans AccountsViewController (une sous-classe de UITableViewController conforme au protocole NSFetchedResultsControllerDelegate) à l'aide d'un NSFetchedResultsController. Pour ajouter un nouveau compte, j'utilise une section de AccountsViewController pour me diriger vers AccountInfoViewController (montré ci-dessous) qui a deux champs textField, un pour le nom et un pour le solde du compte. Lorsque ce dernier est sur le point de disparaître, un nouveau compte est inséré dans le contexte avec le nom et l'équilibre dérivés du textFields. Une fois que le contrôleur parent apparaît (AccountsViewController), il essaie d'enregistrer les modifications et met à jour le tableauView. Maintenant, si j'insère un nouveau compte pour lequel la balance est un nombre entier, la vie est bonne; le contexte est en mesure d'enregistrer les changements, tableView met à jour ses lignes en affichant le compte nouvellement inséré, et je suis heureux. Lorsque j'essaie d'insérer un compte pour lequel la solde est un nombre décimal, l'application se bloque au point où le contexte tente d'enregistrer les modifications. Je n'ai aucune erreur utile quant à la raison pour laquelle cela arrive. Voici le code pour le contrôleur de gestion des TextField:

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!)!) 
    } 
} 

Le MyFormatter est la suivante:

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

et le DataStore montré ci-dessus contient simple Core Data Stack et est responsable de l'insérer dans le contexte:

// 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 
    } 
} 

y at-il des raisons pour lesquelles le contexte ne pour enregistrer les modifications lorsque le balanceField contient un nombre non entier? Merci de lire et de me faire savoir si vous souhaitez que je poste d'autres parties du code.

+0

Qu'est-ce que 'MyFormatter'? Avez-vous vérifié qu'il ne retourne pas indésirable? –

+0

@ TomHarrington: J'ai ajouté le code MyFormatter ci-dessus. Oui, je l'ai vérifié mais il n'est pas inclus dans le code ci-dessus. – linuxfever

+0

Avez-vous imprimé 'account.initBalance' avant de le renvoyer? – sschale

Répondre

4

J'ai finalement été capable de comprendre ce qui se passait. La modification de mon nom d'attribut de initBalance à startingBalance fait que tout fonctionne à nouveau. En fait, changer le nom de l'attribut pour tout ce qui ne commence pas par new ou init fonctionne très bien. J'ai eu l'idée de cela post.

Il semble que lorsque vous utilisez ARC, le nom de votre propriété ne doit pas commencer par le mot new. Il s'avère que initBalance (ou newBalance d'ailleurs) produit le même problème. J'espère que cela aidera la prochaine âme pauvre à courir dans un problème similaire.

+0

Il est assez étrange que cela ne s'est écrasé que pour des valeurs non-entières. Bon travail de travail. –