2015-12-13 3 views
1

Я пытаюсь использовать Sum агрегатную функцию на собственность, но я получаю странное сообщение об ошибке, что я не могу исправить:Использование общая сумма с CoreData

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) 
    } 
} 

Я не знаю, почему в трассировке ошибок есть счетчик. Я выбрал «хороший» подход для подведения итогов?

Спасибо.

ответ

0

Во-первых, это должен быть метод класса. Вы извлекаете произвольные Operation экземпляры, поэтому нет хорошего аргумента, почему это нужно вызывать в контексте одного конкретного экземпляра.

Во-вторых, я не думаю, что это может быть значительно упрощена следующим образом: извлечь все операции с заданными ограничениями, то:

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

или, более «быстро»:

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

Существует нет хорошей заметной причиной для перехода к сложностям и для использования NSDictionaryResultType, если у вас нет проблем с производительностью, что было бы крайне маловероятным.

+0

ОК, спасибо за ваш интерес. Но я не понимаю происхождение 'операций'. Если я прокомментирую все строки относительно NSExpression, 'results' будет содержать массив' Operation', который я не знаю, как агрегировать. Я должен пропустить что-то очевидное ... – Yoryll

+0

Вы должны получить «операции» с соответствующими предикатными фильтрами. Вычисление суммы показано в моем ответе. – Mundi

+0

Извините, мои плохие знания по этому вопросу, я начинаю с Swift, поэтому я не очень хорошо понимаю;) Я удалил все о 'NSExpressions' и изменил запрос выборки следующим образом:' let q1Sum = results.valuesForKeyPath () // -> Значение типа '[Operation]' не имеет значений memberForKeyPath''. Другими словами, как я получаю эту переменную/член 'Operations', которая позволяет мне вызывать значенияForKeyPath (string)? – Yoryll

Смежные вопросы