获取超过 1000 个对象时核心数据崩溃

Posted

技术标签:

【中文标题】获取超过 1000 个对象时核心数据崩溃【英文标题】:Core data crash when fetching over 1000 objects 【发布时间】:2017-07-17 17:09:48 【问题描述】:

当我尝试从 Core Data 获取超过 1000 个 NSManagedObjects 时,我的应用程序崩溃并显示以下消息:

error: (1) I/O error for database at .../Documents/Stores/Model.sqlite.  
SQLite error code:1, 'Expression tree is too large (maximum depth 1000)'
CoreData: error: (1) I/O error for database at .../Documents/Stores/Model.sqlite.  
SQLite error code:1, 'Expression tree is too large (maximum depth 1000)'

我用来获取用户选择的对象的代码是这样的:

NSManagedObjectContext *context = cdh.context;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Spot" inManagedObjectContext:context];
NSError *error = nil;
[request setEntity:entity];
request.includesPropertyValues = NO;

NSMutableArray *subPredicatesArray = [NSMutableArray array];

for (NSString *string in uuidStrings)

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@", @"sID", string];
    [subPredicatesArray addObject:predicate];


NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:subPredicatesArray];
[request setPredicate:compoundPredicate];

NSArray *fetchedObjects = [context executeFetchRequest:request error:&error];

有没有更好的方法来获取 1000 多个不会导致我的应用崩溃的对象?

【问题讨论】:

我不知道这个限制。 :) 在遇到它之前我也没有! 【参考方案1】:

假设 uuidStrings 包含与 sID 属性完全匹配的内容,您应该可以用以下代码替换代码(未经测试):

// remove subPredicatesArray, the loop and compoundPredicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sID IN %@", uuidStrings];
[request setPredicate:predicate];

【讨论】:

这使它工作和运行得更快!我不确定我是如何使用复合谓词而不是您建议的谓词的,但这解决了所有问题!

以上是关于获取超过 1000 个对象时核心数据崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在objective-c中将api响应插入核心数据时逐渐增加内存

通过对象的枚举属性使用 NSPredicate 获取核心数据托管对象的问题

核心数据多对多关系导致获取的结果控制器崩溃

快速从核心数据中获取数据时应用程序崩溃

核心数据:移动到详细视图时获取崩溃

iOS核心数据在后台获取导致崩溃