写入核心数据iOS时遇到麻烦

时间:2014-12-11 19:38:16

标签: ios iphone xcode core-data swift

请帮帮我!当我按下СoreData中的记录按钮时出现以下错误:

这是我的代码(AddViewController):

class AddPersonViewController: UIViewController {

 var textFieldFirstName: UITextField!
  var textFieldLastName: UITextField!
  var textFieldAge: UITextField!
  var barButtonAdd: UIBarButtonItem!

 func createNewPerson(sender: AnyObject){

    let appDelegate = UIApplication.sharedApplication().delegate
      as AppDelegate

    let managedObjectContext = appDelegate.managedObjectContext

    let newPerson =
    NSEntityDescription.insertNewObjectForEntityForName("Person",
      inManagedObjectContext: managedObjectContext!) as? Person

    if let person = newPerson{
      person.firstName = textFieldFirstName.text
      person.lastName = textFieldLastName.text
      if let age = textFieldAge.text.toInt(){
        person.age = age
      } else {
        person.age = 18
      }

      var savingError: NSError?

      if managedObjectContext!.save(&savingError){
        navigationController!.popViewControllerAnimated(true)
      } else {
        println("Failed to save the managed object context")
      }

    } else {
      println("Failed to create the new person object")
    }

 }

 override func viewDidLoad() {
    super.viewDidLoad()

    title = "New Person"

    var textFieldRect = CGRect(x: 20,
      y: 80,
      width: view.bounds.size.width - 40,
      height: 31)

    textFieldFirstName = UITextField(frame: textFieldRect)
    textFieldFirstName.placeholder = "First Name"
    textFieldFirstName.borderStyle = .RoundedRect
    textFieldFirstName.autoresizingMask = .FlexibleWidth
    textFieldFirstName.contentVerticalAlignment = .Center
    view.addSubview(textFieldFirstName)

    textFieldRect.origin.y += 37
    textFieldLastName = UITextField(frame: textFieldRect)
    textFieldLastName.placeholder = "Last Name"
    textFieldLastName.borderStyle = .RoundedRect
    textFieldLastName.autoresizingMask = .FlexibleWidth
    textFieldLastName.contentVerticalAlignment = .Center
    view.addSubview(textFieldLastName)

    textFieldRect.origin.y += 37
    textFieldAge = UITextField(frame: textFieldRect)
    textFieldAge.placeholder = "Age"
    textFieldAge.borderStyle = .RoundedRect
    textFieldAge.autoresizingMask = .FlexibleWidth
    textFieldAge.keyboardType = .NumberPad
    textFieldAge.contentVerticalAlignment = .Center
    view.addSubview(textFieldAge)

    barButtonAdd = UIBarButtonItem(title: "Add",
      style: .Plain,
      target: self,
      action: "createNewPerson:")

    navigationItem.rightBarButtonItem = barButtonAdd

  }

  override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    textFieldFirstName.becomeFirstResponder()
  }

}

TablePerson:

class PersonsListTableViewController: UITableViewController,
NSFetchedResultsControllerDelegate {

  struct TableViewConstants{
    static let cellIdentifier = "Cell"
  }

  var barButtonAddPerson: UIBarButtonItem!
  var frc: NSFetchedResultsController!

  var managedObjectContext: NSManagedObjectContext?{
  return (UIApplication.sharedApplication().delegate
    as AppDelegate).managedObjectContext
  }

  func addNewPerson(sender: AnyObject){
    /* This is a custom segue identifier that we have defined in our
    storyboard that simply does a "Show" segue from our view controller
    to the "Add New Person" view controller */
    performSegueWithIdentifier("addPerson", sender: nil)
  }

  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    barButtonAddPerson = UIBarButtonItem(barButtonSystemItem: .Add,
      target: self,
      action: "addNewPerson:")

  }

  func controllerWillChangeContent(controller: NSFetchedResultsController!) {
    tableView.beginUpdates()
  }

  func controller(controller: NSFetchedResultsController!,
    didChangeObject anObject: AnyObject!,
    atIndexPath indexPath: NSIndexPath!,
    forChangeType type: NSFetchedResultsChangeType,
    newIndexPath: NSIndexPath!) {

      if type == .Delete{
        tableView.deleteRowsAtIndexPaths([indexPath],
          withRowAnimation: .Automatic)
      }

      else if type == .Insert{
        tableView.insertRowsAtIndexPaths([newIndexPath],
          withRowAnimation: .Automatic)
      }

  }

  func controllerDidChangeContent(controller: NSFetchedResultsController!) {
    tableView.endUpdates()
  }

  override func tableView(tableView: UITableView,
    numberOfRowsInSection section: Int) -> Int {

      let sectionInfo = frc.sections![section] as NSFetchedResultsSectionInfo
      return sectionInfo.numberOfObjects

  }

  override func tableView(tableView: UITableView,
    cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{

      let cell = tableView.dequeueReusableCellWithIdentifier(
        TableViewConstants.cellIdentifier,
        forIndexPath: indexPath) as UITableViewCell

      let person = frc.objectAtIndexPath(indexPath) as Person

      cell.textLabel.text = person.firstName + " " + person.lastName
      cell.detailTextLabel!.text = "Age: \(person.age)"

      return cell

  }

  override func setEditing(editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)

    if editing{
      navigationItem.setRightBarButtonItem(nil, animated: true)
    } else {
      navigationItem.setRightBarButtonItem(barButtonAddPerson, animated: true)
    }

  }

  override func tableView(tableView: UITableView,
    commitEditingStyle editingStyle: UITableViewCellEditingStyle,
    forRowAtIndexPath indexPath: NSIndexPath){

      let personToDelete = self.frc.objectAtIndexPath(indexPath) as Person

      managedObjectContext!.deleteObject(personToDelete)

      if personToDelete.deleted{
        var savingError: NSError?

        if managedObjectContext!.save(&savingError){
          println("Successfully deleted the object")
        } else {
          if let error = savingError{
            println("Failed to save the context with error = \(error)")
          }
        }
      }

  }

  override func tableView(tableView: UITableView,
    editingStyleForRowAtIndexPath indexPath: NSIndexPath)
    -> UITableViewCellEditingStyle {
    return .Delete
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    self.title = "Persons"

    navigationItem.leftBarButtonItem = editButtonItem()
    navigationItem.rightBarButtonItem = barButtonAddPerson

    /* Create the fetch request first */
    let fetchRequest = NSFetchRequest(entityName: "Person")

    let ageSort = NSSortDescriptor(key: "age", ascending: true)

    let firstNameSort = NSSortDescriptor(key: "firstName", ascending: true)

    fetchRequest.sortDescriptors = [ageSort, firstNameSort]

    frc = NSFetchedResultsController(fetchRequest: fetchRequest,
      managedObjectContext: managedObjectContext!,
      sectionNameKeyPath: nil,
      cacheName: nil)

    frc.delegate = self
    var fetchingError: NSError?
    if frc.performFetch(&fetchingError){
      println("Successfully fetched")
    } else {
      println("Failed to fetch")
    }

  }

}

和Person.swift:

@objc(Person) class Person: NSManagedObject {

    @NSManaged var age: NSNumber
    @NSManaged var firstName: String
    @NSManaged var lastName: String

}

一切似乎都很好,但我一直收到错误,因此无法写入数据:“无法创建新的人物对象”

这是我的Xcode项目的链接:

download

我不明白为什么我一直在犯错误。请帮忙!

2 个答案:

答案 0 :(得分:0)

"无法创建新的人物对象"正在打印意味着newPersonnil 可能 的一个很好的理由是managedObjectContext为零。你能查一下并报告回来吗?

答案 1 :(得分:0)

我找到解决方案。我xcdatamodeld没有一个类,其中变量由Person描述。谢谢您的回答。抱歉我的愚蠢。