NSUnknownKeyException xcode导航控制器

问题描述:

我不断收到如下所示的异常。我似乎无法弄清楚为什么。请帮忙。将通过电子邮件的代码,如果有人愿意帮助NSUnknownKeyException xcode导航控制器

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ContactDBAppDelegate 0x4d45dc0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key navigationController.' 

ContactDBAppDelegate.h

@interface ContactDBAppDelegate : NSObject <UIApplicationDelegate> { 
NSManagedObjectModel *managedObjectModel; 
NSManagedObjectContext *managedObjectContext;  
NSPersistentStoreCoordinator *persistentStoreCoordinator; 
UINavigationController *navCtrl; 
UIWindow *window; 
} 

@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel; 
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext; 
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator; 
@property (nonatomic, retain) UINavigationController *navCtrl; 
@property (nonatomic, retain) IBOutlet UIWindow *window; 

- (NSString *)applicationDocumentsDirectory; 

ContactDBAppDelegate.m

#import "ContactDBAppDelegate.h" 
#import "RootViewController.h" 

@implementation ContactDBAppDelegate 
@synthesize navCtrl; 
@synthesize window; 


#pragma mark - 
#pragma mark Application lifecycle 

- (void)applicationDidFinishLaunching:(UIApplication *)application {  
RootViewController *rootViewController = [[RootViewController alloc] init]; 
rootViewController.managedObjectContext = [self managedObjectContext] ; 
navCtrl = [[UINavigationController alloc] initWithRootViewController: rootViewController]; 

[window addSubview: navCtrl.view]; 
[window makeKeyAndVisible]; 

[rootViewController release]; // Must release here - locally declared... 
} 

/** 
applicationWillTerminate: saves changes in the application's managed object context before the application terminates. 
*/ 

- (void)applicationWillTerminate:(UIApplication *)application { 

NSError *error = nil; 
if (managedObjectContext != nil) { 
    if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 
     */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
} 
} 


#pragma mark - 
#pragma mark Core Data stack 

/** 
Returns the managed object context for the application. 
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. 
*/ 

- (NSManagedObjectContext *) managedObjectContext { 

if (managedObjectContext != nil) { 
    return managedObjectContext; 
} 

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
if (coordinator != nil) { 
    managedObjectContext = [[NSManagedObjectContext alloc] init]; 
    [managedObjectContext setPersistentStoreCoordinator: coordinator]; 
} 
return managedObjectContext; 
} 


/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created by merging all of the models found in the application bundle. 
*/ 

- (NSManagedObjectModel *)managedObjectModel { 

if (managedObjectModel != nil) { 
    return managedObjectModel; 
} 
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];  
return managedObjectModel; 
} 


/** 
Returns the persistent store coordinator for the application. 
If the coordinator doesn't already exist, it is created and the application's store added to it. 
*/ 

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 

if (persistentStoreCoordinator != nil) { 
    return persistentStoreCoordinator; 
} 

NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"ContactDB.sqlite"]]; 

NSError *error = nil; 
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) { 
    /* 
    Replace this implementation with code to handle the error appropriately. 

    abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button. 

    Typical reasons for an error here include: 
    * The persistent store is not accessible 
    * The schema for the persistent store is incompatible with current managed object model 
    Check the error message to determine what the actual problem was. 
    */ 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
}  

return persistentStoreCoordinator; 
} 


#pragma mark - 
#pragma mark Application's Documents directory 

/** 
Returns the path to the application's Documents directory. 
*/ 
- (NSString *)applicationDocumentsDirectory { 
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
} 


#pragma mark - 
#pragma mark Memory management 

- (void)dealloc { 
[managedObjectContext release]; 
[managedObjectModel release]; 
[persistentStoreCoordinator release]; 
[navCtrl release]; 
[window release]; 
[super dealloc]; 
} 


@end 

RootViewController.h

#import <UIKit/UIKit.h> 
#import "EditViewController.h" 

@interface RootViewController : UITableViewController { 
NSMutableArray *contactItems; 
NSManagedObjectContext *managedObjectContext; 
EditViewController *editViewCtrl; 
} 

@property(nonatomic, retain) NSMutableArray *contactItems; 
@property(nonatomic, retain) NSManagedObjectContext *managedObjectContext; 
@property(nonatomic, retain) EditViewController *editViewCtrl; 

- (void) addItem; 

@end 

RootViewController.m

#import "RootViewController.h" 
#import "Contact.h" 

@implementation RootViewController 
@synthesize contactItems; 
@synthesize managedObjectContext; 
@synthesize editViewCtrl; 

- (void)viewDidLoad { 
[super viewDidLoad]; 

// Set the table style and title 
[self initWithStyle: UITableViewStyleGrouped]; 
self.title = @"Contacts"; 

// Set up the add and delete bar buttons 
self.navigationItem.rightBarButtonItem = self.editButtonItem; 
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target:self action:@selector(addItem)]; 

// Generate a fetch request for reading from the database and set its entity property 
NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName: @"Contact" inManagedObjectContext: managedObjectContext]; 
request.entity = entity; 
[entity release]; 

// Indicate how the fetched results are to be sorted 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: @"name" ascending: YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObjects: sortDescriptor, nil]; 
request.sortDescriptors = sortDescriptors; 
[sortDescriptor release]; 

// Perform the actual fetch from the permanent store and initialize the menuItems array with the results 
NSError *error = nil; 
contactItems = [[managedObjectContext executeFetchRequest: request error: &error] mutableCopy]; 
[request release]; 

// Creat the edit view controller 
editViewCtrl = [[EditViewController alloc] init]; 

} 

- (void) addItem { 
// Insert a new record in the database 
Contact *contact = [NSEntityDescription insertNewObjectForEntityForName: @"Contact" inManagedObjectContext: managedObjectContext]; 
NSError *error = nil; 
[managedObjectContext save: &error]; 

// Insert a new item in the table's data source 
[contactItems insertObject: contact atIndex: 0]; 

// Insert a new row in the table 
NSIndexPath *indexPath = [NSIndexPath indexPathForRow: 0 inSection: 0]; 
[self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: UITableViewRowAnimationFade]; 
} 


- (void) viewWillAppear: (BOOL) animated { 
[super viewWillAppear: animated]; 
if(editViewCtrl.contact) 
{ 
    NSIndexPath *path = [NSIndexPath indexPathForRow: [contactItems indexOfObject: editViewCtrl.contact] inSection: 0]; 
    NSArray *paths = [NSArray arrayWithObjects: path, nil]; 
    [self.tableView reloadRowsAtIndexPaths: paths withRowAnimation: NO]; 
    editViewCtrl.contact = nil; 
} 
} 


#pragma mark Table view methods 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
return 1; 
} 


// Customize the number of rows in the table view. 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
return contactItems.count; 
} 


// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath { 

static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier] autorelease]; 

Contact *contact = [contactItems objectAtIndex: indexPath.row]; 
cell.textLabel.text = [NSString stringWithFormat:@"%@", contact.name]; 
cell.textLabel.font = [UIFont fontWithName: @"Helvetica-Bold" size: 14]; 
cell.textLabel.textColor = [UIColor blackColor]; 

return cell; 
} 




- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
editViewCtrl.contact = [contactItems objectAtIndex: indexPath.row]; 
[self.navigationController pushViewController: editViewCtrl animated:YES]; 
} 




- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 
return YES; 
} 




- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
if (editingStyle == UITableViewCellEditingStyleDelete) 
{ 
    // Delete item from the context and save the context. This removes the item from the permanent store. 
    [managedObjectContext deleteObject: [contactItems objectAtIndex: indexPath.row]]; 
    NSError *error = nil; 
    [managedObjectContext save: &error]; 

    // Remove the item from the table's data source array 
    [contactItems removeObjectAtIndex: indexPath.row]; 

    // Delete the item from the table itself. 
    [tableView deleteRowsAtIndexPaths: [NSArray arrayWithObject: indexPath] withRowAnimation: YES]; 
} 

} 




- (void)dealloc { 
[contactItems release]; 
[managedObjectContext release]; 
[editViewCtrl release]; 
[super dealloc]; 
} 


@end 

EditViewController.h

#import <UIKit/UIKit.h> 

#import "Contact.h" 

@interface EditViewController : UIViewController <UITextFieldDelegate> { 
UILabel *lbl1, *lbl2, *lbl3; 
UITextField *contactName; 
UITextField *contactMobile; 
UITextField *contactHome; 
UIButton *done; 
Contact *contact; 
} 

@property(nonatomic, retain) Contact *contact; 

@end 

EditViewController.m

#import "EditViewController.h" 

#import "Contact.h" 

@implementation EditViewController 
@synthesize contact; 


- (void)viewDidLoad { 
[super viewDidLoad]; 

lbl1 = [[UILabel alloc] initWithFrame: CGRectMake(50, 0, 100, 30)]; 
lbl1.text = @"Contact Name"; 
lbl1.font = [UIFont fontWithName: @"Helvetica" size: 15]; 
lbl1.textColor = [UIColor blueColor]; 
[self.view addSubview: lbl1]; 

contactName = [[UITextField alloc] initWithFrame: CGRectMake(50, 30, 220, 30)]; 
contactName.borderStyle = UITextBorderStyleRoundedRect; 
contactName.textColor = [UIColor blackColor]; 
contactName.delegate = self; 
[self.view addSubview: contactName]; 


lbl2 = [[UILabel alloc] initWithFrame: CGRectMake(50, 70, 100, 30)]; 
lbl2.text = @"Mobile Number"; 
lbl2.font = [UIFont fontWithName: @"Helvetica" size: 15]; 
lbl2.textColor = [UIColor blueColor]; 
[self.view addSubview: lbl2]; 

contactMobile = [[UITextField alloc] initWithFrame: CGRectMake(50, 100, 220, 30)]; 
contactMobile.borderStyle = UITextBorderStyleRoundedRect; 
contactMobile.textColor = [UIColor blackColor]; 
contactMobile.delegate = self; 
[self.view addSubview: contactMobile]; 

lbl3 = [[UILabel alloc] initWithFrame: CGRectMake(50, 140, 100, 30)]; 
lbl3.text = @"Home Number"; 
lbl3.font = [UIFont fontWithName: @"Helvetica" size: 15]; 
lbl3.textColor = [UIColor blueColor]; 
[self.view addSubview: lbl3]; 

contactHome = [[UITextField alloc] initWithFrame: CGRectMake(50, 170, 220, 30)]; 
contactHome.borderStyle = UITextBorderStyleRoundedRect; 
contactHome.textColor = [UIColor blackColor]; 
contactHome.delegate = self; 
[self.view addSubview: contactHome]; 

done = [UIButton buttonWithType: UIButtonTypeRoundedRect]; 
done.frame = CGRectMake(0, 0, 60, 40); 
done.center = CGPointMake(160, 380); 
[done setTitle:@"Done" forState:UIControlStateNormal]; 
[done addTarget:self action:@selector(finishedEditing) forControlEvents:UIControlEventTouchUpInside]; 
[self.view addSubview: done]; 

} 


- (void) finishedEditing { 
[self viewWillDisappear: YES]; 
} 



- (void) viewWillAppear: (BOOL) animated { 
[super viewWillAppear: animated]; 
contactName.text = contact.name; 
contactMobile.text = [NSString stringWithFormat: @"%2.2f", [contact.mobile floatValue]]; 
} 



- (void)viewWillDisappear:(BOOL)animated { 
contact.name = contactName.text; 
contact.mobile = [NSNumber numberWithFloat: [contactMobile.text floatValue]]; 
NSManagedObjectContext *context = contact.managedObjectContext; 
NSError *error = nil; 
[context save: &error]; 
[self.navigationController popViewControllerAnimated: YES]; 

} 



- (void) textFieldDidEndEditing: (UITextField *) txtField { 
if (txtField == contactName) 
    contact.name = txtField.text; 
else if (txtField == contactMobile) 
    contact.mobile = [NSNumber numberWithFloat: [txtField.text floatValue]]; 
} 



- (BOOL) textFieldShouldReturn: (UITextField *) txtField { 
[txtField resignFirstResponder]; 
return YES; 
} 



- (void)dealloc { 
[contact release]; 
[lbl1 release]; 
[lbl2 release]; 
[contactMobile release]; 
[contactName release]; 
[done release]; 
[super dealloc]; 
} 


@end 

Contact.h

#import <Foundation/Foundation.h> 
#import <CoreData/CoreData.h> 


@interface Contact : NSManagedObject { 
@private 
} 
@property (nonatomic, retain) NSString * name; 
@property (nonatomic, retain) NSNumber * work; 
@property (nonatomic, retain) NSNumber * mobile; 
@property (nonatomic, retain) NSNumber * home; 
@property (nonatomic, retain) NSString * address; 
@property (nonatomic, retain) NSString * email; 

@end 

Contact.m

#import "Contact.h" 


@implementation Contact 
@dynamic name; 
@dynamic work; 
@dynamic mobile; 
@dynamic home; 
@dynamic address; 
@dynamic email; 

@end 
+1

请发送引起错误的代码。 – PengOne

+0

已发布it.Hope你可以帮忙 – user1034642

+0

发布你的所有代码几乎和发布它一样糟糕。请指出发生错误的行并只发布相关代码。当调试器可以帮助您将其缩小到几条相关线路时,大多数人都不愿意通读您的整个项目来发现问题。 – PengOne

哇,你发布你的整个应用程序!没有违法意图,但你需要了解视图控制器如何工作。我强烈建议深入研究Apple文档。

您可能有其他问题,但从此开始。你绝不应该明确地发送viewWillDisappear。您的视图控制器将从操作系统收到该消息。你应该做如下修改至少:

- (void) finishedEditing { 
    // DON'T DO THIS 
    // [self viewWillDisappear: YES]; 

    // DO THIS 
    contact.name = contactName.text; 
    contact.mobile = [NSNumber numberWithFloat: [contactMobile.text floatValue]]; 
    NSManagedObjectContext *context = contact.managedObjectContext; 
    NSError *error = nil; 
    [context save: &error]; 
    [self.navigationController popViewControllerAnimated:YES]; 
} 

你应该更改提交到基于适当的用户操作或应用触发的数据模型。被通知视图将消失不是一个好的地方。 你不应该从viewWillDisappear弹出导航控制器堆栈。

- (void)viewWillDisappear:(BOOL)animated { 
    // contact.name = contactName.text; 
    // contact.mobile = [NSNumber numberWithFloat: [contactMobile.text floatValue]]; 
    // NSManagedObjectContext *context = contact.managedObjectContext; 
    // NSError *error = nil; 
    // [context save: &error]; 
    // [self.navigationController popViewControllerAnimated: YES]; 
} 
+0

谢谢你的回应。我对iPhone的编程非常新颖。感谢您的帮助,但它仍然抛出异常。 – user1034642

+0

你显然有其他问题。该错误具体指的是对应用程序委托对象上的键“navigationController”的引用。你的应用程序委托没有'navigationController'作为属性。您发布的代码不会显示此内容。您应该查看您的NIB文件,并查看是否有任何引用应用程序委托中不存在的'navigationController'插座。 – XJones