核心数据不在 iOS 5 中保留

Posted

技术标签:

【中文标题】核心数据不在 iOS 5 中保留【英文标题】:Core Data not persisting in iOS 5 【发布时间】:2011-11-04 14:51:16 【问题描述】:

V。 ios 5

我的 Model2.xcdatamodelId 包含 2 个实体。我的模型被命名为 2,因为我已经有一个名为 Model 的 Singleton 用于一些管理。

因此,我有 Model2.h 和 Model2.m。

我的问题:第一次,我的 Model2 是初始化的,我输入了一些默认数据,然后我提交。效果很好,它说我的 Model2 已正确保存。在我读取我的数据之后,数据从数据库中显示出来......所以它在数据库中是成功的。 但是.. 关闭并杀死我的应用时,我的应用似乎丢失了所有数据.. 并重新开始创建默认数据,因为它是空的...

提示:我认为我的问题可能与初始化有关。在这些行中:

NSArray * paths    = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSURL   * storeUrl = [NSURL fileURLWithPath: [basePath stringByAppendingPathComponent: @"ProjectXYZ.db"]];

由于 ProjectXYZ.db 不存在,它应该创建它吗?...这是我迷路的部分..但它似乎适用于我从事过的另一个项目...:S

这是我的 Model2.h

#import <CoreData/CoreData.h>
#import "Photos_Trophies.h"
#import "Trophies.h"
@interface Model2 : NSObject


// High-level methods.
+ (void) commit;

...

 // Object Retrieval
 + (NSArray*) trophies;

 ...

 // Object Creation
 + (id) trophiesWithTitle:(NSString *)title;

 @end

还有我的 Model2.m

#import "Model2.h"
#import <UIKit/UIKit.h>
static NSManagedObjectContext * ctx;

@implementation Model2


+ (void) initialize 

    NSArray * paths    = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    NSURL   * storeUrl = [NSURL fileURLWithPath: [basePath stringByAppendingPathComponent: @"ProjectXYZ.db"]];
    NSError * error    = nil;

    ctx                            = [[NSManagedObjectContext alloc] init];
    ctx.persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
    ctx.undoManager                = [[NSUndoManager alloc] init];

    if (![ctx.persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType configuration:nil URL:storeUrl options:nil error:&error]) 
        NSLog(@"%@", error);
    

    //TEMPORARY... these are default trophies for example
    if ([[Model2 trophies] count] == 0) 

        [self trophiesWithTitle:@"Saved Trophy Test 1"];
        [self trophiesWithTitle:@"Saved Trophy Test 2"];
        [self trophiesWithTitle:@"Saved Trophy Test 3"];

        [self commit];
    


+ (void) commit 
    NSError* error = nil;

    if (![ctx save:&error]) 
        NSLog(@"ERREUR DANS COMMIT: %@", error.localizedDescription);

        NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
        if(detailedErrors && [detailedErrors count] > 0) 
            for(NSError* detailedError in detailedErrors) 
                NSLog(@"DetailedError: %@", [detailedError userInfo]);
         else 
            NSLog(@"%@", [error userInfo]);
     else
         NSLog(@"Model2 SAVED");


+ (NSArray*) trophies 
   NSFetchRequest* req = [[NSFetchRequest alloc] init];
   req.entity          = [NSEntityDescription entityForName:@"Trophies" inManagedObjectContext:ctx];
   req.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"trophies_title" ascending:YES]];
   NSError* error      = nil;
   NSArray* objects    = [ctx executeFetchRequest:req error:&error];

  return objects;


+ (id) trophiesWithTitle:(NSString *)title 
    Trophies * trophies = [NSEntityDescription insertNewObjectForEntityForName:@"Trophies" inManagedObjectContext:ctx];
    trophies.trophies_title = title;

    return trophies;

【问题讨论】:

【参考方案1】:

你的问题是这样的:NSInMemoryStoreType你需要使用一个持久的后备存储。

做这样的事情:

NSURL *storeUrl = [NSURL fileURLWithPath:[self persistentStorePath]];

NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 
                                              configuration:nil 
                                                        URL:storeUrl 
                                                    options:options 
                                                      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]);
    NSAssert(error == nil, @"error creating persistentStoreCoordinator");   
   

【讨论】:

persistentStorePath 的类型是什么?对于persistentStoreCoordinator 也一样...似乎在这些行之前错过了一些东西? 哦!.. 实际上,我只是更改了您所做的存储类型,NSSQLiteStoreType 与我添加的代码.. 它的工作量为 1。非常感谢那个提示。非常感谢

以上是关于核心数据不在 iOS 5 中保留的主要内容,如果未能解决你的问题,请参考以下文章

iOS:核心数据:如何在托管对象中保留一组有序的对象

iOS - 数据保存一次到核心数据中

xamarin 表单信号器核心客户端处理程序不在 ios 上执行,但在 android 上执行

iOS - 创建核心图像过滤器循环时保留原始图像

核心数据搜索问题 iOS 5

iOS - 在创建核心图像过滤器循环时保留原始图像