应用程序冻结 CoreData 保存

Posted

技术标签:

【中文标题】应用程序冻结 CoreData 保存【英文标题】:App freeze on CoreData save 【发布时间】:2011-03-08 18:45:47 【问题描述】:

我有一个 iPhone 应用程序在保存 CoreData 时有时会死机,然后不会重新启动。我确实有第二个线程使用数据库,但我认为我已经按照模式为该线程创建了一个单独的上下文。这是重新启动的崩溃报告。有什么想法吗?

我尝试将其更改为仅使用一个线程运行,这是进入后台后的最新冻结点。

#0  0x30851b98 in fsync
#1  0x3094e694 in _sqlite3_purgeEligiblePagerCacheMemory
#2  0x3094e6b8 in _sqlite3_purgeEligiblePagerCacheMemory
#3  0x30945372 in sqlite3_compileoption_get
#4  0x30957f06 in sqlite3_extended_errcode
#5  0x3095dc20 in sqlite3_extended_errcode
#6  0x3095dd8e in sqlite3_extended_errcode
#7  0x309646f8 in sqlite3_clear_bindings
#8  0x3098845a in sqlite3_open16
#9  0x3094495a in sqlite3_step
#10 0x31a1dc20 in _execute
#11 0x31acc6e8 in -[NSSQLiteConnection commitTransaction]
#12 0x31aca646 in -[NSSQLiteConnection endPrimaryKeyGeneration]
#13 0x31abeab4 in -[NSSQLCore prepareForSave:]
#14 0x31a4acd0 in -[NSSQLCore saveChanges:]
#15 0x31a1591e in -[NSSQLCore executeRequest:withContext:error:]
#16 0x31a1538a in -[NSPersistentStoreCoordinator executeRequest:withContext:error:]
#17 0x31a48544 in -[NSManagedObjectContext save:]
#18 0x000080aa in -[KPersistence saveManagedObjects:] at KPersistence.m:242
#19 0x00004320 in -[KinKastAppDelegate applicationDidEnterBackground:] at KinKastAppDelegate.m:126

这是我对 saveManagedObjects 的实现

-(BOOL)saveManagedObjects:(NSError **)error

    [persistentStoreCoordinator lock];
    BOOL success = YES;
    if (managedObjectContext != nil) 
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:error]) 
            VLog(@"Unresolved error %@, %@", *error, [*error userInfo]);
            success = NO;
         
    
    [persistentStoreCoordinator unlock];
    return success;

【问题讨论】:

+1 同样的问题,没有解决办法。 我已经为我解决了。问题是将浮点或双精度值保存到整数字段。这导致内存中的浮点 nsnumber 和始终从磁盘上的 db 读取的整数 nsnumber 之间的无限合并循环。 嗯.. 感谢您的提示。我将不得不仔细检查我的所有代码,这看起来需要一段时间:S 是的,我花了很长时间才找到问题所在。我希望以某种方式崩溃有更多有用的数据:-( 【参考方案1】:

当从多个线程使用 Core Data 时,请确保在保存操作之前锁定您的 PSC:

[self.persistentStoreCoordinator lock];
NSManagedObjectContext *context = //your context;
[context save:&error];
if (error) 
    // handle error

[self.persistentStoreCoordinator unlock];

【讨论】:

谢谢,确实我没有做这个锁。但这似乎不是完整的解决方案。 我尝试将其更改为仅在一个线程上运行,但仍然遇到同样的问题。 如果存储文件在多个上下文中解锁运行,则它可能已损坏。删除实际文件并从头开始。 这真的正确吗?我认为上下文会在保存时锁定存储?【参考方案2】:

所以我现在认为问题在于我有时将具有浮点值的 NSNumber 写入整数字段。这导致内存中的副本与从数据库中读取的副本不同,从而导致无限合并循环。但如果你重新启动应用程序,它就可以正常工作,因为从那时起该值只是一个整数。

【讨论】:

以上是关于应用程序冻结 CoreData 保存的主要内容,如果未能解决你的问题,请参考以下文章

核心数据:保存结束时冻结

后台线程方法无法解决冻结问题

UI 冻结与神奇的记录

使用 MagicalRecord 3 的 CoreData 内存设置

BLE + Core Data 导致冻结(信号量等待陷阱)

核心数据冻结所有应用程序