iPhone在保存CoreData时崩溃

3

这是一个不同的情况,与这个问题不同,因为提供的解决方案无效且堆栈不同。

使用coredata保存数据时,会定期发生崩溃。

堆栈跟踪并不完全清楚发生了什么,但我确定正在调用这个例程。这是在这个方法中的save:或接下来的一个。

代码:

-(void)saveWine {
    if ([self validInfo]) {
        Wine *wine =  (Wine *)wineToEdit;
        if (wine == nil) {
            wine = (Wine *)[NSEntityDescription insertNewObjectForEntityForName:@"Wine" inManagedObjectContext:self.managedObjectContext];
        }
        wine.uuid = [Utils createUUID];
        wine.name = self.wineNameField.text;
        wine.vineyard = self.vineyardField.text;
        wine.vintage = [[self numberFormatter] numberFromString:self.vintageField.text];
        wine.timeStamp = [NSDate date];
        wine.rating = [NSNumber numberWithInt:self.ratingControl.selectedSegmentIndex];
        wine.partnerRating = [NSNumber numberWithInt:self.partnerRatingControl.selectedSegmentIndex];
        wine.varietal = self.currentVarietal;
        wine.tastingNotes = self.currentTastingNotes;
        wine.dateTasted = self.currentDateTasted;
        wine.tastingLocation = [[ReferenceDataAccessor defaultReferenceDataAccessor] addEntityForType:TASTING_LOCATION 
                                                                                             withName:self.currentWhereTasted];

        id type = [[ReferenceDataAccessor defaultReferenceDataAccessor] entityForType:WINE_TYPE 
                                                                          withOrdinal:self.typeControl.selectedSegmentIndex];
        wine.type = type;
        NSError *error;
        NSLog(@"Saving %@",wine);
        if (![self.managedObjectContext save:&error]) {
            [Utils showAlertMessage:@"There was a problem saving your wine; try restarting the app" withTitle:@"Problem saving"];
            NSLog(@"Error while saving new wine %@, %@", error, [error userInfo]);
        }
    }
    else {
        NSLog(@"ERROR - someone is calling saveWine with invalid info!!");
    }
}

addEntityForType:withName:代码:

-(id)addEntityForType:(NSString *)type withName:(NSString *)name {

    if ([Utils isStringBlank:name]) {
        return nil;
    }
    id existing = [[ReferenceDataAccessor defaultReferenceDataAccessor] entityForType:type withName:name];

    if (existing != nil) {
        NSLog(@"%@ with name %@ already exists",type,name);
        return existing;
    }


    NSManagedObject *newEntity = [NSEntityDescription insertNewObjectForEntityForName:type 
                                                               inManagedObjectContext:self.managedObjectContext];

    [newEntity setValue:name forKey:@"name"];

    NSError *error;
    if (![self.managedObjectContext save:&error]) {
        [Utils showAlertMessage:[NSString stringWithFormat:@"There was a problem saving a %@",type] withTitle:@"Database Probem"];
        [Utils logErrorFully:error forOperation:[NSString stringWithFormat:@"saving new %@",type ]];
    }
    return newEntity;
}

堆栈跟踪:

Thread 0 Crashed:
0   libSystem.B.dylib               0x311de2d4 __kill + 8
1   libSystem.B.dylib               0x311de2c4 kill + 4
2   libSystem.B.dylib               0x311de2b6 raise + 10
3   libSystem.B.dylib               0x311f2d72 abort + 50
4   libstdc++.6.dylib               0x301dea20 __gnu_cxx::__verbose_terminate_handler() + 376
5   libobjc.A.dylib                 0x319a2594 _objc_terminate + 104
6   libstdc++.6.dylib               0x301dcdf2 __cxxabiv1::__terminate(void (*)()) + 46
7   libstdc++.6.dylib               0x301dce46 std::terminate() + 10
8   libstdc++.6.dylib               0x301dcf16 __cxa_throw + 78
9   libobjc.A.dylib                 0x319a14c4 objc_exception_throw + 64
10  CoreData                        0x3526e83e -[NSManagedObjectContext save:] + 1098
11  Wine Brain                      0x0000651e 0x1000 + 21790
12  Wine Brain                      0x0000525c 0x1000 + 16988
13  Wine Brain                      0x00004894 0x1000 + 14484
14  Wine Brain                      0x00008716 0x1000 + 30486
15  CoreFoundation                  0x31477fe6 -[NSObject(NSObject) performSelector:withObject:withObject:] + 18
16  UIKit                           0x338c14a6 -[UIApplication sendAction:to:from:forEvent:] + 78
17  UIKit                           0x3395c7ae -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 86
18  CoreFoundation                  0x31477fe6 -[NSObject(NSObject) performSelector:withObject:withObject:] + 18
19  UIKit                           0x338c14a6 -[UIApplication sendAction:to:from:forEvent:] + 78
20  UIKit                           0x338c1446 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 26
21  UIKit                           0x338c1418 -[UIControl sendAction:to:forEvent:] + 32
22  UIKit                           0x338c116a -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 350
23  UIKit                           0x338c19c8 -[UIControl touchesEnded:withEvent:] + 336
24  UIKit                           0x338b734e -[UIWindow _sendTouchesForEvent:] + 362
25  UIKit                           0x338b6cc8 -[UIWindow sendEvent:] + 256
26  UIKit                           0x338a1fc0 -[UIApplication sendEvent:] + 292
27  UIKit                           0x338a1900 _UIApplicationHandleEvent + 5084
28  GraphicsServices                0x35d66efc PurpleEventCallback + 660
29  CoreFoundation                  0x314656f8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 20
30  CoreFoundation                  0x314656bc __CFRunLoopDoSource1 + 160
31  CoreFoundation                  0x31457f76 __CFRunLoopRun + 514
32  CoreFoundation                  0x31457c80 CFRunLoopRunSpecific + 224
33  CoreFoundation                  0x31457b88 CFRunLoopRunInMode + 52
34  GraphicsServices                0x35d664a4 GSEventRunModal + 108
35  GraphicsServices                0x35d66550 GSEventRun + 56
36  UIKit                           0x338d5322 -[UIApplication _run] + 406
37  UIKit                           0x338d2e8c UIApplicationMain + 664
38  Wine Brain                      0x000021ba 0x1000 + 4538
39  Wine Brain                      0x00002184 0x1000 + 4484

我不知道为什么我的应用程序的内存位置没有被符号化,但代码路径只导致两个managedObjectContext save:调用。当这种情况发生时,在整个wine对象上进行最终的save:之前,一直调用addEntityForType,为“whereTasted”实体创建一个新对象。

当我再次执行相同的过程时,它可以正常工作。这让我相信这与在添加新位置时应用程序已运行了一段时间有关,但我不确定。

您有什么想法,可以帮助我调试并在下次出现此问题时获取更多信息吗?

2个回答

0
在你的保存调用周围加上 @try-@catch。似乎在保存时抛出了一个异常: 9 libobjc.A.dylib 0x319a14c4 objc_exception_throw + 64 示例:
@try
{
    if (![self.context save:&error]) {
        [[NSApplication sharedApplication] presentError:error];

}
@catch (NSException * e)
{
    NSLog(@"exception saving: %@", e);
    abort();
}

0
你应该尝试激活“运行>在Objective-C异常停止”选项。这使我找到了访问已转换为故障的对象的位置,这是问题的根本原因。(这是最近对我非常有效的建议。感谢Kamchatka。)

我在调试器中做了这件事,但这是在设备上进行的,而不是连接到Xcode... - davetron5000
抱歉,我误解了。这是间歇性的,并且在调试器中从未发生过? - westsider
是的,非常间歇性。在调试器中似乎无法重现。 - davetron5000
我没有答案,但我有几个问题。首先,Wine的类型属性是可选的吗?至于哪个保存:崩溃了,你可以写日志条目到本地文件——仅作为发布前的调试策略。 - westsider
类型是可选的,尽管在实践中应该始终设置它,并且其可能的值应默认始终存在于数据库中。 - davetron5000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接