我创建了一个使用Core Data
的应用程序我在这个应用程序中没有使用应用程序委托。 [managedObjectContext hasChanges] && ![managedObjectContext save:&error]
中没有错误。我已经两天苦苦挣扎了......有人可以告诉我我错过了什么吗?任何帮助将不胜感激。我的代码如下:
DatabaseHelper.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface DatabaseHelper : NSObject
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory;
- (NSManagedObjectContext *) managedObjectContext;
+ (id)sharedInstance;
@end
DatabaseHelper.m
#import "DatabaseHelper.h"
@implementation DatabaseHelper
@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
static DatabaseHelper *sharedInstance = nil;
+ (DatabaseHelper *)sharedInstance {
if (sharedInstance != nil) {
return sharedInstance;
}
static dispatch_once_t pred;
dispatch_once(&pred, ^{
sharedInstance = [[DatabaseHelper alloc] init];
});
return sharedInstance;
}
- (NSManagedObjectContext *) managedObjectContext {
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return __managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Database" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *storeUrl = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Database.sqlite"];
NSLog(@"Location: %@", storeUrl);
NSError *error;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
// Handle the error.
}
return __persistentStoreCoordinator;
}
#pragma mark -
#pragma mark Application's documents directory
/**
Returns the path to the application's documents directory.
*/
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
ViewController.h
#import <UIKit/UIKit.h>
#import "DatabaseHelper.h"
#import "Friends.h"
@interface ViewController : UIViewController{
NSManagedObjectContext *managedObjectContext;
}
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) IBOutlet UILabel *labelText;
-(IBAction)pressButton:(id)sender;
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize managedObjectContext;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
managedObjectContext = [[DatabaseHelper sharedInstance] managedObjectContext];
NSArray *names = [NSArray arrayWithObjects:
@"Steve",
@"John",
@"Paul",
nil];
int startingAge = 25;
for (NSString *name in names) {
Friends *friend = (Friends*) [NSEntityDescription insertNewObjectForEntityForName:@"Friends" inManagedObjectContext:managedObjectContext];
[friend setName:name];
[friend setAge:[NSNumber numberWithInt:startingAge]];
startingAge++;
NSError *error = nil;
if ([managedObjectContext save:&error])
NSLog(@"%@", name);
}
}
-(IBAction)pressButton:(id)sender{
NSError *error = nil;
managedObjectContext = [[DatabaseHelper sharedInstance]managedObjectContext];
if (managedObjectContext != nil) {
NSLog(@"Saved!!");
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();
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
答案 0 :(得分:0)
我相信您每次访问视图控制器时都意识到您正在创建新记录? -viewDidLoad
每次都会开火。
另外,在-viewDidLoad
保存后,您没有检查错误。代码应为:
for (NSString *name in names) {
Friends *friend = (Friends*) [NSEntityDescription insertNewObjectForEntityForName:@"Friends" inManagedObjectContext:managedObjectContext];
[friend setName:name];
[friend setAge:[NSNumber numberWithInt:startingAge]];
startingAge++;
NSError *error = nil;
if ([managedObjectContext save:&error])
NSLog(@"%@", name);
} else {
NSLog(@"Error: %@\n%@", [error localizedDescription], [error userInfo]);
}
}
接下来,在将NSPersistentStore
添加到NSPersistentStoreCoordinator
时,您没有检查错误。如果您没有NSPersistentStore
(由于失败),您将看不到任何写入文件的内容。可能不是你的问题,但你应该总是记录错误:
NSError *error;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
NSLog(@"Error adding store: %@\n%@", [error localizedDescription], [error userInfo]);
}
最后,不需要投射-[NSEntityDescription insertNewObjectForEntityForName: inManagedObjectContext:]
的结果。该方法返回id
,不需要强制转换。您应该考虑在Objective-C中进行转换,以“撒谎到编译器”并且不好。
答案 1 :(得分:0)
我发现这是Xode 5
的一个问题我在Xcode 4.6.3
上运行了我的代码并且它能够正常工作,因为我能够看到SQLite
数据库中的记录。不知道这是一个错误,还是Apple因为安全原因停止向数据库添加记录。希望这有助于某人。
更新
经过进一步研究后,我发现-wal
文件导致数据无法添加到数据库中
将以下内容添加到我的代码后,它现在显示在数据库中。
NSDictionary *options = @{ NSSQLitePragmasOption : @{@"journal_mode" : @"DELETE"} };