【问题标题】:Swift Fetch Request Returning Empty Item In ResultsSwift Fetch 请求在结果中返回空项目
【发布时间】:2016-04-09 18:41:35
【问题描述】:

我有一个项目,我需要执行获取核心数据实体的最新“更新”日期的获取请求。但是,当我实际检查查询返回的结果时,我看到了一些相当奇怪的行为。除了包含日期的“正确”结果之外,结果还包括一个空字典项。每次都会发生这种情况,无论基础数据是什么样的。更奇怪的是,如果我在 xcode 中打开 sql 日志记录并对 sqllite db 执行记录的查询,它会产生正确的结果而没有额外的条目。我不太确定我在这里做错了什么,任何帮助将不胜感激。

构建和执行查询的函数:

func queryForContactDate(context:NSManagedObjectContext) -> AnyObject?
{

    var expressionDescriptions = [AnyObject]();

    let expressionDescription = NSExpressionDescription()

    // Name the column
    expressionDescription.name = "maxUpdated"
    // Use an expression to specify what aggregate action we want to take and
    // on which column. In this case max on the update_at column
    expressionDescription.expression = NSExpression(format: "@max.updated_at")
    // Specify the return type we expect
    expressionDescription.expressionResultType = .DateAttributeType
    // Append the description to our array
    expressionDescriptions.append(expressionDescription)

    // Build out our fetch request the usual way
    let request = NSFetchRequest(entityName: Contact.entityName())

    // Specify we want dictionaries to be returned
    request.resultType = .DictionaryResultType

    // Hand off our expression descriptions to the propertiesToFetch field.
    request.propertiesToFetch = expressionDescriptions

    // Our result is going to be an array of dictionaries.
    var results:[[String:AnyObject]]?

    // Perform the fetch. This is using Swfit 2, so we need a do/try/catch
    do {
        results = try context.executeFetchRequest(request) as? [[String:AnyObject]]
    } catch _ {
        // If it fails, ensure the array is nil
        results = nil
    }

    return results![0];
}

如果我在最后放置一个断点并打印出它产生的结果:

Printing description of results:
▿ Optional([[:], ["maxUpdated": 2015-12-30 20:05:31 +0000]])
  ▿ Some : 2 elements
    - [0] : 0 elements
    ▿ [1] : 1 elements
      ▿ [0] : 2 elements
        - .0 : "maxUpdated"
        - .1 : 2015-12-30 20:05:31 +0000

【问题讨论】:

  • 你能用 context.executeFetchRequest(request) 打印出来吗?您可能正在投射实际上不是 [[String: AnyObject]] 的东西。特别是在将 objc 移植到 Swift 的 API 的角落,字典/数组会发生一些奇怪的事情
  • 我怀疑你是在正确的轨道上,但打印并不是特别有启发性。这是我得到的: [{ }, { maxUpdated = "2015-12-30 20:05:31 +0000"; }]
  • 然后我会在 fetch 方法中放置一个断点并追溯它并查看请求的来源/空字典何时到达那里
  • 我很乐意,但不幸的是,如果不访问 NSManagedObjectContext 的源代码,我无法更深入地调试对 context.executeFetchRequest 的调用。

标签: swift core-data aggregate-functions nsfetchrequest


【解决方案1】:

获取最大或最小项的传统 Core Data 方法是使用 1 的获取限制进行查询并按该键排序。就像在这个 Objective-C 代码中一样:

+ (NSFetchRequest *) requestForStatusWithMaxID {

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName: kAMStatusEntity];

    NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey: kAMTwID ascending:NO];

    request.sortDescriptors = @[sd];
    request.fetchLimit = 1;

    return request;

} // +requestForStatusWithMaxID

为您的updated_at 属性修改上述内容非常简单。

【讨论】:

  • 是的,可以通过这种方式进行提取,但是随着基础表的大小变大,性能会受到影响。此外,如果我尝试 SUM 等其他聚合函数,我会看到同样的行为。简单地排序和获取第一个结果对这些没有帮助。
  • 任何没有索引的查询,包括您上面列出的查询,都会随着表的增长而出现扩展问题。你的桌子有多大? 100、1,000、10,000、1M 行?如果它很大,那么您需要一个索引 - 两种查询样式。
猜你喜欢
  • 2015-11-14
  • 2021-07-08
  • 2012-06-12
  • 2023-03-28
  • 2015-03-17
  • 2022-11-14
  • 1970-01-01
  • 2022-09-24
  • 2020-04-28
相关资源
最近更新 更多