将sum聚合与CoreData一起使用

时间:2015-12-13 11:18:54

标签: core-data sum swift2

我尝试在属性上使用Sum聚合函数,但是我得到一个奇怪的错误,我无法纠正:

2015-12-13 11:32:29.280 YoBuM[634:42509] -[NSDecimalNumber count]: unrecognized selector sent to instance 0x618000025ce0 2015-12-13 11:32:29.281 YoBuM[634:42509] -[NSDecimalNumber count]: unrecognized selector sent to instance 0x618000025ce0 2015-12-13 11:32:29.286 YoBuM[634:42509] ( 0 CoreFoundation 0x00007fff8a8e0ae2 __exceptionPreprocess + 178 1 libobjc.A.dylib 0x00007fff97b6473c objc_exception_throw + 48 2 CoreFoundation 0x00007fff8a8e3b9d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x00007fff8a81c601 ___forwarding___ + 1009 4 CoreFoundation 0x00007fff8a81c188 _CF_forwarding_prep_0 + 120 5 Foundation 0x00007fff9796cff6 +[_NSPredicateUtilities _getCommonTypeFor:] + 76 6 Foundation 0x00007fff9796d30a +[_NSPredicateUtilities sum:] + 144 7 Foundation 0x00007fff977d2cff -[NSFunctionExpression expressionValueWithObject:context:] + 1094 ...

我的代码是:

import Foundation
import CoreData

@objc(Operation)
class Operation: NSManagedObject {
    @NSManaged var amount: NSNumber?
    @NSManaged var date: NSDate?
    @NSManaged var days: NSNumber?
    @NSManaged var designation: String?
    @NSManaged var isDebit: NSNumber?
    @NSManaged var element: Element?

    class func tests(appDel: AppDelegate, forElement: Element) -> (q1: Double, q2: Double, q3: Double, q4: Double) {
        let moc = appDel.managedObjectContext
        let request = NSFetchRequest(entityName: "Operation")

        let expressionDesc = NSExpressionDescription()
        expressionDesc.name = "sumOfAmount"
        let amountExpr = NSExpression(forKeyPath: "amount")
        expressionDesc.expression = NSExpression(forFunction: "sum:", arguments: [amountExpr])
        expressionDesc.expressionResultType = .DoubleAttributeType
        request.propertiesToFetch = [expressionDesc]
        request.resultType = .DictionaryResultType

        let elementPredicate = NSPredicate(format: "element = %@", forElement)
        let creditPredicate = NSPredicate(format: "isDebit = %@", true)

        let year = (forElement.budget as! Budget).year!.integerValue
        var minDate = Utils.getDate("01/01/\(year)")
        var maxDate = Utils.getDate("04/01/\(year)")
        let datesPredicate = NSPredicate(format: "(date >= %@) AND (date < %@)", minDate, maxDate)
        let predicates = NSCompoundPredicate(andPredicateWithSubpredicates: [elementPredicate, creditPredicate, datesPredicate])
        request.predicate = predicates

        do {
            //error is here when some entities are found for the given predicates
            let results = try moc.executeFetchRequest(request)

            // ...
        }
        catch {
            fatalError("Oops: \(error).")
        }
        //return (q1, q2, q3, q4)
    }
}

我不知道为什么错误跟踪中有一个计数选择器。 我选择了好的&#34;接近这里求和?

感谢。

1 个答案:

答案 0 :(得分:0)

首先,这应该是一个类方法。您正在获取任意Operation个实例,因此没有好的论据,为什么应该在一个特定实例的上下文中调用它。

其次,我认为这可以大大简化如下:获取具有给定约束的所有操作,然后:

let q1Sum = (operations as NSArray).valueForKeyPath("@sum.amount").doubleValue

或更“迅速”:

let q1Sum = operations.map { $0.amount.doubleValue }.reduce(0, combine: +)

进入NSExpression复杂性和使用NSDictionaryResultType没有明显的明显理由,除非您遇到性能问题,这是非常不可能的。