如何使用 NSExpression 使用自定义函数设置 NSFetchRequest propertiesToFetch

Posted

技术标签:

【中文标题】如何使用 NSExpression 使用自定义函数设置 NSFetchRequest propertiesToFetch【英文标题】:How to set NSFetchRequest propertiesToFetch with a custom function using NSExpression 【发布时间】:2016-08-12 06:23:36 【问题描述】:

我在 CoreData 实体中有一个 String 类型的属性“消息”,它存储文本,有时还包括 URL。现在我需要从实体中获取所有 url。

    let predicate = NSPredicate(format:"message CONTAINS[cd] %@", "http")
    let fetchRequest = self.getfetchRequest(entityName: "Messages", sectionKey:nil, predicate:predicate)
    let expressionDescription = NSExpressionDescription()
    expressionDescription.name = "urlFromMsg"
    expressionDescription.expressionResultType = .StringAttributeType
    let expression = NSExpression(forFunction: "toUrl", arguments: [NSExpression(forKeyPath: "message")])

    expressionDescription.expression = expression
    fetchRequest.propertiesToFetch = [expressionDescription]
    fetchRequest.resultType = NSFetchRequestResultType.DictionaryResultType

这里的 toUrl 是一个扩展 String 的自定义函数。

extension String 
    func toUrl()->[String]?
        let detector = try! NSDataDetector(types: NSTextCheckingType.Link.rawValue)
        let matches = detector.matchesInString(self, options: [], range: NSRange(location: 0, length: self.utf16.count))
        var urls = [String]()
        for match in matches 
            urls.append((self as NSString).substringWithRange(match.range))
        
        return urls
    

我在这条线上崩溃了

let expression = NSExpression(forFunction: "toUrl", arguments: [NSExpression(forKeyPath: "message")])

如何在 NSExpression 中正确设置自定义方法。

【问题讨论】:

参见useyourloaf.com/blog/core-data-queries-using-expressions - 但并非所有自定义函数都与 CD 兼容.. 【参考方案1】:

当在 fetch 请求和 SQLite 支持的 Core Data 存储中使用自定义 NSExpression 时,Core Data 会尝试将表达式转换为 SQL 查询。这有助于提高性能,但这意味着并非所有有效的NSExpressions 都适用于 Core Data。

具体来说,依赖自定义函数的NSExpression 不能与 Core Data fetch 一起使用,因为 Core Data 无法将任意代码转换为 SQL。

您需要从提取中删除此NSExpression,并使用提取结果转换为 URL。您也可以切换到非 SQLite Core Data 存储,但由于各种原因,这通常会更糟,除非您的持久存储包含非常少量的数据。

【讨论】:

以上是关于如何使用 NSExpression 使用自定义函数设置 NSFetchRequest propertiesToFetch的主要内容,如果未能解决你的问题,请参考以下文章

使用“现在”的 NSExpression 函数

NSExpression 使用 sqrt: 函数导致 NSInvalidArgumentException

如何使 NSExpression 的 expressionForFunction:withArguments: 尊重获取请求的谓词

如何阻止 NSExpression 舍入

如何从 NativeScript 调用 Objective-C NSExpression(format: ....)?

使用 NSExpression 计算小于值?