Core data 核心数据在多次保存时冻结应用程序
我无法将数据保存在核心数据中。我必须点击按钮在数据库中保存多个图书信息。当我点击按钮时,我调用该方法并将图书信息保存在数据库中。对于前三次点击,它很好地保存了图书信息,用户界面也响应良好。当我第四次单击按钮时,ui在保存结束时冻结 代码如下所示Core data 核心数据在多次保存时冻结应用程序,core-data,moc,Core Data,Moc,我无法将数据保存在核心数据中。我必须点击按钮在数据库中保存多个图书信息。当我点击按钮时,我调用该方法并将图书信息保存在数据库中。对于前三次点击,它很好地保存了图书信息,用户界面也响应良好。当我第四次单击按钮时,ui在保存结束时冻结 代码如下所示 +(void) storeBookInfo:(NSDictionary *) bookInfo inContext:(NSManagedObjectContext *) ctx { AppDelegate *appDelegate = (App
+(void) storeBookInfo:(NSDictionary *) bookInfo inContext:(NSManagedObjectContext *) ctx {
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *tempCtx = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[tempCtx setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[tempCtx setUndoManager:nil];
NSNotificationCenter *notify = [NSNotificationCenter defaultCenter];
[notify addObserver:self
selector:@selector(mergeChanges:)
name:NSManagedObjectContextDidSaveNotification
object:tempCtx];
NSFetchRequest *req = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:tempCtx];
[req setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bid==%@", [bookInfo objectForKey:@"bid"]];
[req setPredicate:predicate];
[req setFetchLimit:1];
[req setReturnsObjectsAsFaults:NO];
NSArray *bookObjects = [tempCtx executeFetchRequest:req error:nil];
if([bookObjects count] > 0){
NSError *err;
Book *wi = [bookObjects objectAtIndex:0];
wi.purchaseInfo = [NSNumber numberWithInt:[[bookInfo objectForKey:@"purchaseInfo"] intValue]];
if (![tempCtx save:&err]) {
NSLog(@"Problem saving book info..");
NSLog(@"err: %@", [err userInfo]);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tempCtx undo];
tempCtx = nil;
} else {
NSLog(@"Book saved. in if part");
tempCtx = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
else {
Book *book = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:tempCtx];
book.bid = [bookInfo objectForKey:@"bid"];
book.title = [bookInfo objectForKey:@"title"];
book.thumbnailImgId = [bookInfo objectForKey:@"imageUrl"];
book.downloadState = [NSNumber numberWithInt:0];
book.pid = [bookInfo objectForKey:@"pid"];
book.purchaseInfo = [NSNumber numberWithInt:[[bookInfo objectForKey:@"purchaseInfo"] intValue]];
book.discription = [bookInfo objectForKey:@"desc"];
NSError *err;
if (![tempCtx save:&err]) {
NSLog(@"Problem saving book ifo..");
NSLog(@"err: %@", [err userInfo]);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[tempCtx undo];
tempCtx = nil;
} else {
NSLog(@"Book saved.");
tempCtx = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}
}
+ (void)mergeChanges:(NSNotification*)notification
{
AppDelegate *theDelegate = [[UIApplication sharedApplication] delegate];
[[theDelegate managedObjectContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:notification waitUntilDone:YES];
}
我已经创建了一个临时MOC,因为代码在后台线程中,每次保存后我都会发送通知
第四次点击按钮“应用程序冻结”。我被困在这一点上。*假设:
+storeBookInfo:inContext:
始终在BG线程中调用
使用弧
*请注意:
<代码> >代码> > StuteBooKof:InWrime:<代码>是类本身,<代码> ReaveValue:<代码>它将删除所有的观察信息(您可能错过某个时间的合并,考虑使用<代码> ReaveValue:No:对象:< /Cord>,而不是立即取消TEMPPCTX)
您正在使用:NSPrivateQueueConcurrencyType
但未使用它的performBlock:
或performBlockAndWait:
方法(考虑使用nsConfiginementConcurrencyType
)
如果+mergeChanges:
将在主线程上被调用,则应用程序将被卡住
(考虑加入:
NSAssert(![NSThread isMainThread],@"The application will get stuck");
以确保或修改合并流
)