2014-01-22 2 views
0

Я создал приложение, которое использует 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

Как вы определяете, что данные не сохраняются? Я запустил ваш код, и он работал для меня (я сделал запрос на выборку в viewDidLoad, во второй раз, когда я запустил приложение, и закомментировал весь код, кроме получения moc). – rdelmar

+0

@rdelmar Не следует ли добавлять записи в базу данных SQLite? – Dwill

+0

Да, они должны. – rdelmar

ответ

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 был «ложным компилятору» и плохим.

0

я понял, что это проблема с Xode 5 я побежал мой код на Xcode 4.6.3 и он работал, как это я должен был в состоянии видеть записи в базе данных SQLite. Не знаю, является ли это ошибкой или Apple перестала добавлять записи в базу данных по соображениям безопасности. Надеюсь, это поможет кому-то.

Update

После дальнейших исследований я обнаружил, что файл -wal приводит данные не будут добавлены в базу данных после добавления ниже моего кода он теперь показывает в базе данных.

NSDictionary *options = @{ NSSQLitePragmasOption : @{@"journal_mode" : @"DELETE"} }; 
Смежные вопросы