崩溃后核心数据为空
Posted
技术标签:
【中文标题】崩溃后核心数据为空【英文标题】:Core data empty after crash 【发布时间】:2014-11-12 22:57:41 【问题描述】:我正在模拟崩溃以测试我的应用程序如何响应,并注意到我的core data
在重新启动应用程序时为空。到现在为止,使用核心数据和NSFetchRequest
一直运行良好——我可以终止应用程序或关闭手机,并且数据始终保留。我正在使用核心数据将 URLS 存储到存储在 NSFileManager
中的音频文件。当我重新启动应用程序时,我可以看到文件仍在 NSFileManager
中,但 NSFetchRequest
返回的计数为零,而我的 tableview
为空。有没有人经历过这种情况?
编辑:我一直在使用这两行来模拟崩溃:
NSArray *array = @[];
array[1];
在我的主视图控制器的viewDidLoad
中,我调用以下代码:
self.managedDocument = [OSManagedDocument getInstance];
[self.managedDocument setUpDocument];
managedDocument 是一个单例,包含我所有的数据管理方法。
@property (nonatomic, strong) NSManagedObjectContext * managedObjectContext;
+(OSManagedDocument*) getInstance
static OSManagedDocument* _instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
_instance = [[OSManagedDocument alloc] init];
);
return _instance;
-(void) setUpDocument
if(self.document == nil)
NSFileManager * fileManager = [NSFileManager defaultManager];
NSURL * documentsDirectory = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
NSString * documentName = @"MyRecordings";
self.url = [documentsDirectory URLByAppendingPathComponent:documentName];
self.document = [[UIManagedDocument alloc] initWithFileURL:self.url];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[self.url path]];
if(fileExists)
[self.document openWithCompletionHandler:^(BOOL success)
if(success)
[self documentIsReady];
];
else
[self.document saveToURL:self.url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success)
if(success)
[self documentIsReady];
else
NSLog(@"Fail");
];
-(void) documentIsReady
if(self.document.documentState ==UIDocumentStateNormal)
self.managedObjectContext = self.document.managedObjectContext;
NSLog(@"context is ready");
[self fetchControllerFiles];
[self recordingCount];
-(int) recordingCount
NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"Recording"];
NSError *error;
request.predicate = nil;
request.sortDescriptors =nil;
NSArray * recordings = [self.managedObjectContext executeFetchRequest:request error:&error];
NSLog(@"recordings count %lu", (unsigned long)recordings.count);
return (int)[recordings count];
当我的应用在崩溃后重新启动时,我会调用以下代码:
-(void) appBecameActive:(NSNotification *)notification
self.managedDocument = [OSManagedDocument getInstance];
我调用这个方法来添加核心数据
-(void) saveRecording:(NSMutableDictionary*) recordPackage inManagedObjectContext:(NSManagedObjectContext*) context
Recording * recording = [NSEntityDescription insertNewObjectForEntityForName:@"Recording" inManagedObjectContext:context];
recording.trackTitle = [recordPackage objectForKey:@"track label"];
recording.audioURL = [[recordPackage objectForKey:@"audioURL"] absoluteString];
recording.timeAdded = [NSDate date];
recording.waveData = [recordPackage objectForKey:@"waveData"];
recording.minAmpl = [recordPackage objectForKey:@"minAmpl"];
recording.recordingNumber = [recordPackage objectForKey:@"recordingNumber"];
【问题讨论】:
[OSManagedDocument getInstance]
是否返回值?还是nil
? setUpDocument
方法通过你的if else
语句的路径是什么?
OSManagedDocument 没有返回零。对于路径,它识别filesExist
为真,success
为真,然后调用[self documentIsReady]
UIDocumentStateNormal
是真的吗?
是的。输入 IF 语句永远不会有问题。我一直在通过 NSArray *array = @[];
然后调用 array[1];
来模拟崩溃
您是否将上下文保存在任何地方?您应该有类似:[context save:&error]
以确保将更新保存回数据库。
【参考方案1】:
我一直依靠自动保存来处理保存,它运行良好,直到我开始强制崩溃以查看应用程序如何恢复。由于每次崩溃后数据都会消失,因此我决定尝试手动保存,并且成功了。现在,即使在强制崩溃之后,数据也会出现。我假设这意味着自动保存没有及时发生。不完全确定如何解释,但手动保存上下文解决了我的问题。
[self.document saveToURL:self.document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success)
if(success)
NSLog(@" NEW FILE SAVED");
else
NSLog(@"FAIL TO SAVE");
];
【讨论】:
自动保存仅定期发生,而不是在进行更改时自动发生。因此,在您进行更改和自动保存之间有一段时间。如果您在此期间崩溃,您的数据将会丢失。您的手动保存可避免此问题。以上是关于崩溃后核心数据为空的主要内容,如果未能解决你的问题,请参考以下文章