valueForUndefinedKey错误

时间:2016-10-18 18:22:58

标签: swift xcode

每当我从TableViewController转到ViewController查看数据时,我都会收到一个终端错误。我很确定我实际上并没有以某种方式初始化数据,但由于我是xCode和Swift的新手,我不知道如何解决我的问题。

TableViewController(GasManifoldLogSheet)代码

import UIKit
import Foundation
import CoreData

class GasManifoldLogSheet: UIViewController, UITextFieldDelegate, NSFetchedResultsControllerDelegate, UITableViewDelegate {

// MARK: References
@IBOutlet weak var tableView: UITableView!

var items = [NSManagedObject]()
var currentIndexPath: NSIndexPath?


// MARK: Random Functions
func viewWillAppear() {
}

override func viewDidLoad() {
    super.viewDidLoad()

    title = "Gas Manifold Logs"
    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")

    fetchData()

}


// MARK: UITableView Data Source

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    print("Message for NSManagedObject counting")
    return items.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! as UITableViewCell
    let item = items[indexPath.row]

    cell.textLabel?.text = item.valueForKey("date") as? String


    print("Message for NSManagedObject -> Cell name")
    return cell
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    currentIndexPath = indexPath
    self.performSegueWithIdentifier("saveSegue", sender: nil)
}



// MARK: Functions
func fetchData() {
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedObjectContext = appDelegate.managedObjectContext

    let fetchRequest = NSFetchRequest(entityName: "GasManifoldLog")

    do{
        let fetchedResults = try managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
        items = fetchedResults
    } catch {
        print("error fetching results of search")
    }

}

func initializeFetchedResultsController() {
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    let fetchRequest = NSFetchRequest(entityName: "GasManifoldLog")

    let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: appDelegate.managedObjectContext, sectionNameKeyPath: "date", cacheName: nil)
    fetchedResultsController.delegate = self

    do {
       try fetchedResultsController.performFetch()
    } catch let error as NSError {
        print(error)
    }
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "saveSegue" {

        let indexPath = self.tableView.indexPathForSelectedRow!
        let theSelectedRow = [items[indexPath.row]]
        let theDestination = segue.destinationViewController as! GasManifoldLogSheetEdit

        print("All Variables have been set for sending data to the next view controller")

        theDestination.carriedItems = theSelectedRow

        print("Data was sent to the next view controller")
    } else {
        print("prepareForSegue function was called, but the segue identifier was not listed for a saved transition")
    }
    }




}

这里是ViewController(GasManifoldLogSheetEdit)代码(我现在只试图让一个标签实际显示文字)

import UIKit
import CoreData

class GasManifoldLogSheetEdit: UIViewController, UITextFieldDelegate, NSFetchedResultsControllerDelegate {

// MARK: References
@IBOutlet weak var displayInitials: UILabel!
@IBOutlet weak var displaySIN: UILabel!
@IBOutlet weak var displayRSP: UILabel!
@IBOutlet weak var displaySP: UILabel!
@IBOutlet weak var displayLSP: UILabel!
@IBOutlet weak var textfieldNotes: UITextField!

var carriedItems = [NSManagedObject]()


// MARK: Functions

override func viewDidLoad() {
displayInitials.text = valueForKey("initials") as? String
}

继承我的错误代码

[<EMGS.Users: 0x7fd6e3c264b0> (entity: Users; id: 0xd000000000040000 <x-coredata://91BF1700-C6BD-489A-9886-3BE9404ABE6F/Users/p1> ; data: <fault>), <EMGS.Users: 0x7fd6e3c2f3b0> (entity: Users; id: 0xd000000000080000 <x-coredata://91BF1700-C6BD-489A-9886-3BE9404ABE6F/Users/p2> ; data: <fault>)]
    [<EMGS.Users: 0x7fd6e3c264b0> (entity: Users; id: 0xd000000000040000 <x-coredata://91BF1700-C6BD-489A-9886-3BE9404ABE6F/Users/p1> ; data: {
initials = AA;
loginStatus = 0;
password = A;
username = A;
}), <EMGS.Users: 0x7fd6e3c2f3b0> (entity: Users; id: 0xd000000000080000 <x-coredata://91BF1700-C6BD-489A-9886-3BE9404ABE6F/Users/p2> ; data: <fault>)]
Message for NSManagedObject counting
Message for NSManagedObject counting
Message for NSManagedObject counting
Message for NSManagedObject counting
Message for NSManagedObject -> Cell name
All Variables have been set for sending data to the next view controller
Data was sent to the next view controller
2016-10-18 14:03:44.245 EMGS[76584:1316311] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<EMGS.GasManifoldLogSheetEdit 0x7fd6e3de3ad0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key initials.'
*** First throw call stack:
(
0   CoreFoundation                      0x0000000101a53e65 __exceptionPreprocess + 165
1   libobjc.A.dylib                     0x0000000103793deb objc_exception_throw + 48
2   CoreFoundation                      0x0000000101a53aa9 -[NSException raise] + 9
3   Foundation                          0x0000000101eaf888 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 226
4   EMGS                                0x00000001014bcc63 _TFC4EMGS23GasManifoldLogSheetEdit11viewDidLoadfS0_FT_T_ + 211
5   EMGS                                0x00000001014bcec2 _TToFC4EMGS23GasManifoldLogSheetEdit11viewDidLoadfS0_FT_T_ + 34
6   UIKit                               0x0000000102406f98 -[UIViewController loadViewIfRequired] + 1198
7   UIKit                               0x00000001024072e7 -[UIViewController view] + 27
8   UIKit                               0x0000000102bb1f87 -[_UIFullscreenPresentationController _setPresentedViewController:] + 87
9   UIKit                               0x00000001023d6f62 -[UIPresentationController initWithPresentedViewController:presentingViewController:] + 133
10  UIKit                               0x0000000102419c8c -[UIViewController _presentViewController:withAnimationController:completion:] + 4002
11  UIKit                               0x000000010241cf2c -[UIViewController _performCoordinatedPresentOrDismiss:animated:] + 489
12  UIKit                               0x000000010241ca3b -[UIViewController presentViewController:animated:completion:] + 179
13  UIKit                               0x00000001029933e0 __74-[UIStoryboardPresentationSegueTemplate newDefaultPerformHandlerForSegue:]_block_invoke + 133
14  UIKit                               0x0000000102999f5c -[UIStoryboardSegueTemplate _performWithDestinationViewController:sender:] + 460
15  UIKit                               0x0000000102999d5f -[UIStoryboardSegueTemplate _perform:] + 82
16  UIKit                               0x0000000102409c0c -[UIViewController performSegueWithIdentifier:sender:] + 99
17  EMGS                                0x00000001014aa336 _TFC4EMGS19GasManifoldLogSheet9tableViewfS0_FTCSo11UITableView23didSelectRowAtIndexPathCSo11NSIndexPath_T_ + 182
18  EMGS                                0x00000001014aa3bf _TToFC4EMGS19GasManifoldLogSheet9tableViewfS0_FTCSo11UITableView23didSelectRowAtIndexPathCSo11NSIndexPath_T_ + 79
19  UIKit                               0x00000001023b3d5e -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1887
20  UIKit                               0x00000001023b3fb3 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 388
21  UIKit                               0x000000010227c4a2 _runAfterCACommitDeferredBlocks + 317
22  UIKit                               0x000000010228fc01 _cleanUpAfterCAFlushAndRunDeferredBlocks + 95
23  UIKit                               0x000000010229baf3 _afterCACommitHandler + 90
24  CoreFoundation                      0x000000010197f367 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
25  CoreFoundation                      0x000000010197f2d7 __CFRunLoopDoObservers + 391
26  CoreFoundation                      0x0000000101974f2b __CFRunLoopRun + 1147
27  CoreFoundation                      0x0000000101974828 CFRunLoopRunSpecific + 488
28  GraphicsServices                    0x0000000106090ad2 GSEventRunModal + 161
29  UIKit                               0x0000000102270610 UIApplicationMain + 171
30  EMGS                                0x00000001014bb20d main + 109
31  libdyld.dylib                       0x00000001042a592d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

编辑1 这是CoreData模型 http://imgur.com/a/zScvu

在我的应用程序中,我有一个TableView,显示Gas Manifold Sheets的所有条目(GasManifoldLogSheet)。从该TableView,您可以按创建按钮访问下一个ViewController并输入数据以在CoreData中创建实体。第二个用于数据输入的ViewController被调用(GasManifoldLogSheetNewRecord)。点击保存按钮后,您将被移回原始的TableView(GasManifoldLogSheet),在那里您将看到填充的实体列表或日志表。

当我在我的应用程序上选择单独的日志表时,它会执行一个名为(GasManifoldLogSheetEdit)的第三个ViewController的segue,您可以在其中查看/编辑数据。

每当我尝试使用键 initials (在viewDidLoad()函数内)中的值来更改displayInitials的文本时,据我所知应该在变量/ NSManagedObject carryItems ,我收到了上面发布的错误。

编辑2 下面是第二个ViewController(GasManifoldLogSheetNewRecord)

的代码
import UIKit
import CoreData

class GasManifoldLogSheetNewRecord: UIViewController {

// MARK: References
@IBOutlet weak var txtDate: UITextField!
@IBOutlet weak var txtSupplyPressure: UITextField!
@IBOutlet weak var txtLeftBankPressure: UITextField!
@IBOutlet weak var txtRightBankPressure: UITextField!
@IBOutlet weak var txtSideInUse: UITextField!
@IBOutlet weak var initials: UITextField!
@IBOutlet weak var txtDescription: UITextField!


// MARK: Loading Scripts
func viewWillAppear() {
}

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    // Automatic Date
    let currentDate = NSDate()
    let dateFormatter = NSDateFormatter()

    dateFormatter.dateStyle = NSDateFormatterStyle.LongStyle
    let convertedDate = dateFormatter.stringFromDate(currentDate)
    txtDate.text = convertedDate

    // Automatic Initials
    let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
    let context:NSManagedObjectContext = appDel.managedObjectContext

    let request = NSFetchRequest(entityName: "Users")
    request.returnsObjectsAsFaults = false
    request.predicate = NSPredicate(format: "loginStatus = %@", "1")

    let results:NSArray = try! context.executeFetchRequest(request)

    if(results.count > 0) {
        let res = results[0] as! NSManagedObject
        initials.text = res.valueForKey("initials") as? String

    } else {
        print("Login Didn't Work")
    }

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


// MARK: Opening and closing keyboard

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

@IBAction func backgroundTap(sender: UITapGestureRecognizer) {
    self.view .endEditing(true)
}


// MARK: Functions
@IBAction func btnCreate(sender: AnyObject) {
    let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
    let context:NSManagedObjectContext = appDel.managedObjectContext
    let newGasManifoldLog = NSEntityDescription.insertNewObjectForEntityForName("GasManifoldLog", inManagedObjectContext: context) as NSManagedObject

    if (txtDate.text!.isEmpty || initials.text!.isEmpty) {
        let alertController = UIAlertController(title: "Error", message:
            "Date and Initials are required.", preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))

        self.presentViewController(alertController, animated: true, completion: nil)
        return
    }

    newGasManifoldLog.setValue(txtDate.text, forKey: "date")
    newGasManifoldLog.setValue(txtSupplyPressure.text, forKey: "supplyPressure")
    newGasManifoldLog.setValue(txtLeftBankPressure.text, forKey: "leftBankPressure")
    newGasManifoldLog.setValue(txtRightBankPressure.text, forKey: "rightBankPressure")
    newGasManifoldLog.setValue(txtSideInUse.text, forKey: "sideInUse")
    newGasManifoldLog.setValue(initials.text, forKey: "initials")
    newGasManifoldLog.setValue(txtDescription.text, forKey: "jobDescription")

    do {
        try context.save()
        print(newGasManifoldLog)
        print("Object Saved")
    } catch let error as NSError {
        print(error)
    }

}




/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

2 个答案:

答案 0 :(得分:0)

阅读错误消息。关键部分是

  

[EMGS。 GasManifoldLogSheetEdit 0x7fd6e3de3ad0&gt; valueForUndefinedKey :]:此类与键缩写不符合键值编码。&#39;

然后在代码中查找valueForKey("initials")

displayInitials.text = valueForKey("initials") as? String

由于没有明确的接收者,你实际上是打电话

displayInitials.text = <instance of GasManifoldLogSheetEdit>.valueForKey("initials") as? String

当然会崩溃。

您应该将carriedItems声明为单个对象

var carriedItem = NSManagedObject!

并传递prepareForSegue

中的项目
let theSelectedRow = items[indexPath.row]
...
theDestination.carriedItem = theSelectedRow

现在你可以写

displayInitials.text = carriedItem.valueForKey("initials") as? String

如评论中所述,我们建议您在super

中致电viewDidLoad()
override func viewDidLoad() {
   super.viewDidLoad
   ...

答案 1 :(得分:0)

我读到我必须向下转换NSManagedObject。这是我的解决方案

    override func viewDidLoad() {
    for items in carriedItems as [NSManagedObject] {
        print(items)
        displayInitials.text = items.valueForKey("initials") as? String
    }

使用该代码,我现在可以使我的NSManagedObject中的值可读。