Tôi có một lỗi ngẫu nhiên đã khiến tôi thất vọng trong nhiều tháng mà tôi không thể hiểu được. Tôi sẽ nói rằng nó thất bại ít hơn 1 trong 1000 lần. Tôi phải có CoreData cấu hình không chính xác nhưng tôi không thể tìm ra hoặc tạo lại nó. Ý chính cơ bản là tôi nhận được một số thông tin từ máy chủ và sau đó tôi cập nhật một đối tượng CoreData trong một chủ đề nền. Đối tượng CoreData không cần thiết ngay lập tức cho giao diện người dùng.Cập nhật Chủ đề Nền của CoreData Có Ngẫu nhiên EXC_BAD_ACCESS KERN_INVALID_ADDRESS Lỗi
Tất cả điều này được thực hiện trong DataService có tham chiếu đến NSManagedObjectContext ban đầu được tạo trong AppDelegate. Lưu ý: Bất cứ điều gì mà tài liệu tham khảo [DataService sharedService] sử dụng AppDelegate.NSManagedObjectContext:
@interface DataService : NSObject {}
@property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
@end
Khi trở về máy chủ với dữ liệu phương pháp updateProduct được gọi là:
@implementation DataService
+ (NSManagedObjectContext*) newObjectContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; //step 1
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
[context setPersistentStoreCoordinator:appDelegate.persistentStoreCoordinator];
[context setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
[appDelegate.managedObjectContext observeContext:context];
return context;
}
+(void) saveContext:(NSManagedObjectContext*) context
{
NSError *error = nil;
if (context != nil) {
if ([context hasChanges] && ![context save:&error]) {
// Handle Error
}
}
}
+(void) updateProduct: (Product*) product
{
if(product == nil)
return;
//run in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, (unsigned long)NULL), ^(void){
//create private managed object
NSManagedObjectContext *context = [DataService newObjectContext];
CoreDataProduct* coreProduct = [DataService product:product.productId withObjectContext:context];
if(product != nil)
{
//copy data over from product
coreProduct.text = product.text;
//ERROR HAPPENS HERE on save changes
[DataService saveContext:context];
}
//remove background context listening from main thread
[DataService.managedObjectContext stopObservingContext:context];
});
}
@end
tôi sử dụng chung NSManagedObjectContext + Helper.h danh mục tệp nổi trên GitHub và lỗi EXC_BAD_ACCESS KERN_INVALID_ADDRESS của tôi xảy ra trong phương thức [DataService.managedObjectContext mergeChangesFromNotification: (NSNotification *)] gọi số này
@implementation NSManagedObjectContext (Helper)
- (void) mergeChangesFromNotification:(NSNotification *)notification
{
//ERROR HAPPENS HERE
[self mergeChangesFromContextDidSaveNotification:notification];
}
@end
Tôi không thể hiểu tại sao phương thức mergeChangesFromContextDidSaveNotification không thành công một cách ngẫu nhiên. Tôi nghĩ rằng lỗi là do mất tham chiếu đến managedObjectContext được chia sẻ ban đầu. Mặc dù nếu đó là sự thật, tôi đoán tôi sẽ mong đợi các lỗi được trong phương pháp updateProduct và không phải trong lớp thể loại.
Tôi cho rằng cả phương thức newObjectContext và phương thức stopObservingContext đều tham chiếu đến managedObjectContext trên chuỗi nền từ chuỗi chính. Vì tôi đang tạo một managedObjectContext riêng, thậm chí tôi có cần phải làm cho bối cảnh chính được chia sẻ nhận biết về ngữ cảnh riêng tư không? Nếu vậy, tôi đang làm nó không chính xác?
Cảm ơn bạn đã trợ giúp.
Có lẽ bạn nên hiển thị các phương pháp không, 'mergeChanges ...'. – Mundi
Mục cuối cùng trong dấu vết ngăn xếp là - [NSManagedObjectContext _mergeChangesFromDidSaveDictionary: usingObjectIDs:] mà tôi không nghĩ là cung cấp nhiều thông tin. – dirkoneill
Có lẽ bạn không nên sử dụng GCD nhưng các API tương thích ngữ cảnh như 'performBlock'. Ngoài ra, đặt một điểm ngắt tại dòng và kiểm tra thông báo. – Mundi