好事实:
我狩猎的错误:
[__NSCFNumber length]: unrecognized selector sent to instance
发生了崩溃,我没有打电话给任何'长度'我的CoreDataManager中的属性都不在我的AppDelegate类证人:控制台
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(352)> Will merge
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(355)> Did merge
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(352)> Will merge
<AppDelegate.m:(355)> Did merge
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<MyTableViewController.m:(134)> Fetched results controller did fetch
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<CoreDataManager.m:(338)> Saved data from server
<AppDelegate.m:(352)> Will merge
<CoreDataManager.m:(338)> Saved data from server
[__NSCFNumber length]: unrecognized selector sent to instance 0x13318050
部分代码 - 合并MOC
- (void)managedObjectContextDidSave:(NSNotification *)notification
{
NSManagedObjectContext *sender = (NSManagedObjectContext *)[notification object];
if ((sender != self.managedObjectContext) &&
(sender.persistentStoreCoordinator == self.managedObjectContext.persistentStoreCoordinator))
{
dispatch_async(dispatch_get_main_queue(), ^{
DebugLog(@"Will merge");
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
DebugLog(@"Did merge");
});
}
}
更新1
根据Cocoanetics提示,我创建了一个NSNumber类别来检查谁在调用length
。我得到了你在下面看到的内容,以及 [__ NSCFNumber _fastCStringContents:]:无法识别的选择器发送到实例的崩溃。
更新2 启用僵尸没有帮助=(
答案 0 :(得分:1)
确保您仅观察其他MOC的通知。如果你保存在那里,这会触发另一个这样的通知,你可能会在一次或两次迭代后无限循环,因为ARC已经释放了一个对象。
答案 1 :(得分:1)
你的听起来像是一个记忆问题。检查您的ARC所有权限定符并启用NSZombies。启用NSZombies将帮助您缩小过早释放的对象。
启用僵尸时,您会看到“发送到已解除分配的实例的消息”。检查哪个对象过早释放并更新您的问题。
答案 2 :(得分:1)
好吧,经过几个月和几个小时,我终于得到了解决方案。它有效,我很想听听有关原因的一些意见。
所以,正如我所说的,保存工作100%,以及合并通知。如果我将NSFetchedResultsController委托设置为nil,则没有问题。但是,将委托设置为我的UIViewController,使应用程序崩溃。
我认为可能是因为我的代码在触发委托方法时。但该应用程序甚至在此之前就崩溃了。所以我按照Cocoanetics提示创建了一个类别,并试图弄清楚谁在调用NSNumber对象的length
方法。之后,我看到NSPredicate在遇到崩溃之前正在调用- (BOOL)evaluateWithObject:(id)object;
。以同样的方式,我做了一个类别来覆盖它:
@interface NSPredicate (PractiPredicate)
- (BOOL)evaluateWithObject:(id)object;
@end
@implementation NSPredicate (PractiPredicate)
- (BOOL)evaluateWithObject:(id)object
{
NSLog(@"Evaluate was called. Object class %@", NSStringFromClass([object class]));
MyManagedObject *myManagedObject = object;
NSLog(@"Is fault? %d", myManagedObject.isFault);
NSLog(@"myManagedObject changed and already have propertyA? %d", myManagedObject.propertyA != nil);
return YES;
}
@end
所以,令我惊讶的是,它起作用了,并生成了以下日志:
调用了评估。对象类MyManagedObject
是错吗? 0
myManagedObject已更改且已有propertyA? 1
我决定打印“Is fault?”因为我认为这个混乱与NSManagedObject故障有关,但是,对于它打印的内容,它不是。
评论问题:您认为这可能会产生这个问题吗?
答案 3 :(得分:0)
问题很可能不在于您发布的代码,而在于您如何处理获取的结果控制器委托中的更改。这些只是由合并引发的。
答案 4 :(得分:0)
我有同样的问题,在我的情况下,我发现崩溃的原因是不正确的谓词。我有一个这样的谓词:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"attribute > 0"];
其中attribute是一个字符串。我把它更正为:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"attribute.length > 0"];
现在,我的代码运行正常。确保检查代码中的所有谓词,因为这也可能是导致此崩溃的原因。