核心数据 - 数据未存储在数据库中

时间:2014-01-22 21:43:20

标签: ios core-data ios7 singleton

我创建了一个使用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

2 个答案:

答案 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"} };