0

我有一个核心数据项目。当我对表视图进行拉动刷新时,它会在后台线程上创建一个新上下文,更新数据库,然后将这些更新合并到主上下文中。一切正常(我认为),但现在我遇到了以下崩溃:

2013-09-13 19:01:40.873 My App[2926:a0b] -[__NSCFString controllerWillChangeContent:]: unrecognized selector sent to instance 0xc26b370
2013-09-13 19:02:00.629 My App[2926:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString controllerWillChangeContent:]: unrecognized selector sent to instance 0xc26b370'
*** First throw call stack:
(
    0   CoreFoundation                      0x027795e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x01e888b6 objc_exception_throw + 44
    2   CoreFoundation                      0x02816903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
    3   CoreFoundation                      0x0276990b ___forwarding___ + 1019
    4   CoreFoundation                      0x027694ee _CF_forwarding_prep_0 + 14
    5   CoreData                            0x002217b0 -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 2080
    6   Foundation                          0x015dbe39 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
    7   CoreFoundation                      0x027d5524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
    8   CoreFoundation                      0x0272d07b _CFXNotificationPost + 2859
    9   Foundation                          0x01515b91 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98
    10  CoreData                            0x001264a3 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 83
    11  CoreData                            0x0013be96 -[NSManagedObjectContext _mergeChangesFromDidSaveDictionary:usingObjectIDs:] + 3734
    12  CoreData                            0x0013afed -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 429
    13  My App                            0x0000bc45 -[MAManager updateMainContext:] + 245
    14  libobjc.A.dylib                     0x01e9a81f -[NSObject performSelector:withObject:] + 70
    15  Foundation                          0x0155dc18 __NSThreadPerformPerform + 285
    16  CoreFoundation                      0x027028af __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    17  CoreFoundation                      0x0270223b __CFRunLoopDoSources0 + 235
    18  CoreFoundation                      0x0271f30e __CFRunLoopRun + 910
    19  CoreFoundation                      0x0271eb33 CFRunLoopRunSpecific + 467
    20  CoreFoundation                      0x0271e94b CFRunLoopRunInMode + 123
    21  GraphicsServices                    0x0348e9d7 GSEventRunModal + 192
    22  GraphicsServices                    0x0348e7fe GSEventRun + 104
    23  UIKit                               0x0067b94b UIApplicationMain + 1225
    24  My App                            0x00003442 main + 146
    25  libdyld.dylib                       0x0236d725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException

这是它正在中断的相关代码:

 // merge changes to main context,fetchedRequestController will automatically monitor the changes and update tableview.
- (void)updateMainContext:(NSNotification *)notification {
    assert([NSThread isMainThread]);
    NSLog(@"Merging changes from context.");
    [[self managedObjectContext] mergeChangesFromContextDidSaveNotification:notification];
    [self save]; // update fetched results controllers
}

// this is called via observing "NSManagedObjectContextDidSaveNotification" from the background thread data load
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification {
    NSLog(@"Context saved!");
    if (notification.object != [self managedObjectContext]) {
        NSLog(@"Background context propagating to main context.");
        [self performSelectorOnMainThread:@selector(updateMainContext:) withObject:notification waitUntilDone:NO];
    }
}

有谁知道我为什么会收到此错误以及如何解决?

4

3 回答 3

0

为通知注册的某些对象看起来已被释放,其地址被重新用于存储字符串,而不是预期的。

为您的方案打开僵尸程序,再次运行它,并确定正在向哪个对象发送通知。然后确保在需要时保持对象处于活动状态。

于 2013-09-13T23:24:22.230 回答
0

您的崩溃是带有方法的无法识别的选择器[__NSCFString controllerWillChangeContent:]。此方法在 FRC 的委托上调用,但不知何故,您在 NSString 上执行了回调,它没有实现该方法。您可以发布在该视图控制器中设置 NSFetchedResultsController 的代码吗?

于 2013-09-13T23:38:50.393 回答
0

多个保存请求同时进入(来自不同的托管对象上下文,但仍然来自不同的线程)似乎是一个问题。解决方案是将保存操作包装在 @synchronized 块中,以确保保存操作是原子的并且不会同时发生:

- (void) save {
    // lock and wait if another save operation is in progress
    @synchronized([self class]) {
        NSError *error;
        if (![self save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", error);
        }
    }
}
于 2013-09-15T21:03:57.723 回答