【问题标题】:Coredata on iPhone, setFetchBatchSize & setPropertiesToFetch in one RequestiPhone 上的 Coredata、setFetchBatchSize 和 setPropertiesToFetch 在一个请求中
【发布时间】:2010-11-12 23:24:05
【问题描述】:

我正在编写一个基于 coredata 的 iPhone 应用程序来显示食谱。为了提高性能,在 TableView 中显示它们时,我想启用批处理 (-setFetchBatchSize:) 并仅获取“名称”属性 (-setPropertiesToFetch:)。当我同时打开两者时,它不起作用并且列表为空。只要我注释掉下面代码中标记的行之一,它就可以正常工作。

我在这里缺少什么?就不能两者兼得吗?

NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Rezept" inManagedObjectContext:chk_context]];
// *snip*

//BATCHING
[fetchRequest setFetchBatchSize:25];  

NSDictionary *entityProperties = [[NSEntityDescription entityForName:@"Rezept" inManagedObjectContext:chk_context] propertiesByName];

//PROPERTIES
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"name"]]]; 

【问题讨论】:

    标签: iphone objective-c core-data


    【解决方案1】:

    我远非核心数据专家,但在我的情况下,我成功地完成了这项工作。我认为 setFetchBatchSize 和 setPropertiesToFetch 之间的“冲突”更多是核心数据工作方式的副作用,而不是本身的错误。

    就我而言,我做了两次提取。在第一个中,结果类型设置为 NSManagedObjectResultType,我使用 setFetchBatchSize 来限制主动带入内存的数据量。在第二次提取中,我根据单个属性填充标题数组并将结果类型设置为 NSDictionaryResultType 并将 fetchBatchSize 设置为 0(无限)。

    根据测试,此方案完美运行。初始提取中的所有记录(带有实际的 managedObjects)都受到 fetchBatchSize 的限制和内存限制。第二次 fetch 返回一个简单的标题字典。与遍历所有实际的 managedObjects 来访问 title 属性相比,这占用的内存要少得多。第二次提取需要禁用 fetchBatchSize 是有道理的,因为它将完全填充的字典作为单个结果返回,并且批处理不合适。

    我不确定我在这里是否 100% 清楚(核心数据术语有点神秘......)但最重要的是我认为一切都按预期工作。

    【讨论】:

    • +1 这个答案是有道理的。 setPropertiesToFetch: 方法不做任何事情,除非结果类型是 NSDictionaryResultType (这在答案中提到但没有明确说明)。我假设当 setFetchBatchSize: 被注释掉时代码似乎可以工作,因为托管对象被提取而不仅仅是所需的属性。
    • 一个有趣的提示:如果您查看 NSFetchRequest 类参考中setPropertiesToFetch: 的文档,看起来有人可能发布了一个错误并且他们的评论无意中(?)进入了“讨论”部分.建议此人在文档中声明该值仅在 resultType 设置为 NSDictionaryResultType 时使用,因为他/她“只是浪费了一个小时认为它适用于托管对象结果类型”。好笑!
    【解决方案2】:

    Hunter 你可以在手机上使用 com.apple.CoreData.SQLDebug 1 但不能使用模拟器

    【讨论】:

    • 你不应该把 cmets 伪装成答案,风格不好。
    【解决方案3】:

    看起来很像您在 CoreData 中发现了一个错误。您可以通过打开 SQL 日志记录来确定验证 - 我猜打开这两个选项会生成稍微无效的 SQL。

    您要使用的选项是“com.apple.CoreData.SQLDebug 1” - 您可以从命令行指定它,或在程序中设置默认值。

    -威尔

    【讨论】:

    • CoreData 调试框架只能在桌面上运行,不是吗?我认为没有 iPhone 版本的调试框架。
    • 我不是在谈论调试框架。我是说,设置一个环境变量或默认值以在普通 CoreData 框架中触发额外的日志记录。
    • 威尔,你真的让这个在手机上工作了吗?我没有运气,这个人暗示这是一个已知的错误:stackoverflow.com/questions/822906/…
    【解决方案4】:

    更新:当我 NSLog 后出现错误

    [fetchedResultsController performFetch:&error];
    

    我得到“NSUnderlyingException = 数据库出现损坏。(无效的主键);”。但我不知道这意味着什么以及它与启用这两种方法有什么关系。

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-18
      • 2013-07-17
      相关资源
      最近更新 更多