请帮帮我!当我按下С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项目的链接:
我不明白为什么我一直在犯错误。请帮忙!
答案 0 :(得分:0)
"无法创建新的人物对象"正在打印意味着newPerson
是nil
。 可能 的一个很好的理由是managedObjectContext
为零。你能查一下并报告回来吗?
答案 1 :(得分:0)
我找到解决方案。我xcdatamodeld没有一个类,其中变量由Person描述。谢谢您的回答。抱歉我的愚蠢。