gpt4 book ai didi

iphone - 合并 CoreData 托管上下文时出现异常/崩溃

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:45:56 26 4
gpt4 key购买 nike

我在尝试将托管上下文(在后台线程上运行)与我的主托管上下文(在主线程上)合并时遇到以下异常。我似乎无法在我自己的@try 表达式中捕捉到异常。有没有人对这个问题有任何见解?

我正在使用默认的合并策略,但我不确定这是正确的 - 这个问题是间歇性的 - 很少发生但会导致我的应用程序崩溃。

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 0

Last Exception Backtrace:
0 CoreFoundation 0x37e3b8bf __exceptionPreprocess + 163
1 libobjc.A.dylib 0x319211e5 objc_exception_throw + 33
2 CoreData 0x344b7ea5 -[NSSQLiteStatement cachedSQLiteStatement] + 1
3 CoreData 0x344b774f -[NSSQLiteConnection prepareSQLStatement:] + 55
4 CoreData 0x3455b049 -[NSSQLChannel selectRowsWithCachedStatement:] + 61
5 CoreData 0x34586d63 newFetchedRowsForFetchPlan_MT + 783
6 CoreData 0x344bfb07 -[NSSQLCore newRowsForFetchPlan:] + 351
7 CoreData 0x34565011 -[NSSQLCore fetchRowForObjectID:] + 1005
8 CoreData 0x344d1a57 -[NSSQLCore newValuesForObjectWithID:withContext:error:] + 195
9 CoreData 0x344d0f83 _PFFaultHandlerLookupRow + 423
10 CoreData 0x3450e111 -[NSFaultHandler fulfillFault:withContext:] + 25
11 CoreData 0x34518999 -[NSManagedObject(_NSInternalMethods) _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:] + 77
12 CoreData 0x345178ef -[NSManagedObject(_NSInternalMethods) _newAllPropertiesWithRelationshipFaultsIntact__] + 79
13 CoreData 0x345284db -[NSManagedObjectContext(_NSInternalChangeProcessing) _establishEventSnapshotsForObject:] + 47
14 CoreData 0x3452694b -[NSManagedObjectContext deleteObject:] + 155
15 CoreData 0x345238a1 -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 813
16 CoreData 0x34522c35 -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 189
17 myapp 0x0008f0e9 0x8d000 + 8425
18 CoreFoundation 0x37d9a22b -[NSObject performSelector:withObject:] + 43
19 Foundation 0x31d75757 __NSThreadPerformPerform + 351
20 CoreFoundation 0x37e0fb03 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
21 CoreFoundation 0x37e0f2cf __CFRunLoopDoSources0 + 215
22 CoreFoundation 0x37e0e075 __CFRunLoopRun + 653
23 CoreFoundation 0x37d914dd CFRunLoopRunSpecific + 301
24 CoreFoundation 0x37d913a5 CFRunLoopRunInMode + 105
25 GraphicsServices 0x3790ffcd GSEventRunModal + 157
26 UIKit 0x35221743 UIApplicationMain + 1091

我在 nsoperation 的 start() 中初始化背景上下文,如下所示:

AppDelegate *appController = [[UIApplication sharedApplication] delegate];
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[appController setPersistentStore:_managedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedDeletedObjects:) name:NSManagedObjectContextDidSaveNotification object:_managedObjectContext];

我还设置了一个通知事件,当在后台管理的上下文中删除对象时调用该事件,然后回调执行:

-(void)receivedDeletedObjects:(NSNotification *)note
{
AppDelegate *appController = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [self managedObjectContext];
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:) withObject:note waitUntilDone:NO];

}

这就是代码。我有 4 个不同的后台线程,每个线程都有自己的托管上下文,以这种方式与主上下文合并做同样的事情。我想知道多个线程同时进入 mergeChangesFromContextDidSaveNotification 但不应该是这种情况,因为它总是在主线程上调用。

最佳答案

这个怎么样:

(全部在 AppDelegate 中,从后台线程调用 freshContextForBackgroundTask 并使用 save: 触发合并。)注意 syncObj 是一个普通的 NSObject 实例,当使用许多后台线程时(或者只是运气不好)调度)

-(NSManagedObjectContext*) freshContextForBackgroundTask {
@synchronized(syncObj) {
NSManagedObjectContext* r = [[NSManagedObjectContext alloc] init];
[r setPersistentStoreCoordinator:self.managedObjectContext.persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundContextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:r];
return r;
}
}


- (void)backgroundContextDidSave:(NSNotification *)notification {
/* Make sure we're on the main thread when updating the main context */
//NSLog(@"merging change: %@",notification);
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *context = [self managedObjectContext];
// this for loop may not be needed for your purpose.
for(NSManagedObject *object in [[notification userInfo] objectForKey:NSUpdatedObjectsKey]) {
[[context objectWithID:[object objectID]] willAccessValueForKey:nil];
}
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];

});
}

你的方法看起来很奇怪。尤其是当您将应用委托(delegate)的持久存储设置为 (nil) 新初始化的上下文之一时。

关于iphone - 合并 CoreData 托管上下文时出现异常/崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9234548/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com