2017-05-31 105 views
3

我的工作Objective-C與CoreData,我得到下面的錯誤是...一類的NSManagedObject「的NSManagedObject必須有一個有效NSEntityDescription

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An NSManagedObject of class 'NSManagedObject' must have a valid NSEntityDescription.'

我加CoreData到我的項目。我在viewControllerA中創建saveData方法,我在viewControllerB中調用它。

在這種情況下,我得到錯誤,如果我調用viewDidLoad中的saveData方法viewControllerA它工作正常。

In AppDelegate.h 

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; 
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; 
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 

In AppDelegate.m 

#pragma mark - Core Data stack 

@synthesize managedObjectContext = _managedObjectContext; 
@synthesize managedObjectModel = _managedObjectModel; 
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator; 

- (NSURL *)applicationDocumentsDirectory { 
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.brninfotech._607_introToCoreDataFinal" in the application's documents directory. 
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
} 

- (NSManagedObjectModel *)managedObjectModel { 
// The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. 
if (_managedObjectModel != nil) { 
    return _managedObjectModel; 
} 
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"VehicleNumberDataBase" withExtension:@"momd"]; 
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
return _managedObjectModel; 
} 

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. 
if (_persistentStoreCoordinator != nil) { 
    return _persistentStoreCoordinator; 
} 

// Create the coordinator and store 

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"VehicleNumberDataBase.sqlite"]; 


// NSLog(@"StoreURL is %@",storeURL); 
NSError *error = nil; 
NSString *failureReason = @"There was an error creating or loading the application's saved data."; 
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { 
    // Report any error we got. 
    NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 
    dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; 
    dict[NSLocalizedFailureReasonErrorKey] = failureReason; 
    dict[NSUnderlyingErrorKey] = error; 
    error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; 
    // Replace this 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. 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 

return _persistentStoreCoordinator; 
} 


- (NSManagedObjectContext *)managedObjectContext { 
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) 
if (_managedObjectContext != nil) { 
    return _managedObjectContext; 
} 

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

#pragma mark - Core Data Saving support 

- (void)saveContext { 
NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 
if (managedObjectContext != nil) { 
    NSError *error = 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. 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 
} 
} 


in viewControllerA viewDidLoad 

self.ad = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 
self.VehicleNumberED = [NSEntityDescription entityForName:@"VehicleNumberEntity" inManagedObjectContext:self.ad.managedObjectContext]; 

- (void)saveData { 

NSManagedObject * managedObj = [[NSManagedObject alloc]initWithEntity:self.VehicleNumberED insertIntoManagedObjectContext:self.ad.managedObjectContext]; 

[managedObj setValue:self.textFieldString forKey:@"vehicleNumberAtt"]; 

NSError * errorObj; 
[self.ad.managedObjectContext save:&errorObj]; 

if (errorObj) { 
    NSLog(@"Something goes wrong"); 
}else { 
    NSLog(@"Saved Successfully"); 
} 

NSFetchRequest * fetReq = [NSFetchRequest fetchRequestWithEntityName:@"VehicleNumberEntity"]; 

NSError * fetchErrorObj; 

self.storedDataArray = [self.ad.managedObjectContext executeFetchRequest:fetReq error:&fetchErrorObj]; 


NSLog(@"array count is %lu", self.storedDataArray.count); 

for (int i=0; i<self.storedDataArray.count; i++) { 

    self.storedManagedObj = [self.storedDataArray objectAtIndex:i]; 

    self.vehicleNumberArray = [self.storedManagedObj valueForKey:@"vehicleNumberAtt"]; 

} 

NSLog(@"Vehicle number is : %@", [self.storedManagedObj valueForKey:@"vehicleNumberAtt"]); 

} 

in ViewVontrollerB 

- (IBAction)saveVehicleNumberButton:(UIButton *)sender { 

VehicleDetailsViewController *vedvc = [[VehicleDetailsViewController alloc]init]; 
vedvc = [self.storyboard instantiateViewControllerWithIdentifier:@"VeDVC"]; 
vedvc.textFieldString = self.vehicleNumberTextField.text; 
[vedvc saveData]; 

[self.navigationController pushViewController:vedvc animated:YES]; 
} 

回答

1

這裏的問題是,你在執行前[vedvc saveData]顯示vedvc視圖控制器。此時,vedvc尚未顯示,因此其viewDidLoad尚未執行。因此,self.adself.VehicleNumberED都是零。因此錯誤:實體描述爲零。

最簡單的解決方法是將這兩個變量(adVehicleNumberED)的初始化移動到saveData方法。但是你可能會更好地重新考慮你的代碼結構。

相關問題