从核心数据获取实体属性总和时出错

时间:2017-06-25 12:41:30

标签: swift core-data

我已经创建了一个类来管理我的CoreData实体[命名:DBHelper](所有CRUD操作,它工作正常。但是,我需要得到一个名为subtotal的属性的总和,但是我&# 39; m收到以下错误:

thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0)

我的代码出了什么问题?

实体类

import Foundation
import CoreData

@objc(Odetails)
public class Odetails: NSManagedObject {
    public let entityName = "Odetails"
}

实体扩展:

extension Odetails {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Odetails> {
        return NSFetchRequest<Odetails>(entityName: "Odetails")
    }

    @NSManaged public var pname: String?
    @NSManaged public var price: Int16?
    @NSManaged public var qty: Int16?
    @NSManaged public var subtotal: Int16?

}

核心数据助手类:

import CoreData

class DBHelper {


    var context: NSManagedObjectContext

    init(context: NSManagedObjectContext){
        self.context = context
}

    // ......


    func getsum() -> Int16{
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Odetails")
        do {
            let response = try context.fetch(fetchRequest)
            var sum : Int16 = 0
            for res in response as! [Odetails]{
                sum +=  res.subtotal
            }
            return sum
        } catch let error as NSError {
            // failure
            print(error.localizedDescription)
            return 0
        }
    }


}

使用:

override func viewDidLoad() {
    super.viewDidLoad()

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    let dbhelper = DBHelper(context: context)
    print("count : \(dbhelper.getAll().count)")
    print("Sum : \(dbhelper.getsum())")    //  ERROR HERE
    var sum : Int16 = 0
    for r in dbhelper.getAll() {  // Method Return [Odetails]

        sum += r.subtotal      // OR ERROR HERE

    }
    print(" Sum : \(sum)")
}

非常感谢任何帮助

2 个答案:

答案 0 :(得分:4)

有点offtopic,这是获取Core Data中特定属性总和的更有效方法

func getSum() -> Int16
{
    let description = NSExpressionDescription()
    description.name = "sumSubtotal"
    description.expression = NSExpression(forKeyPath: "@sum.subtotal")
    description.expressionResultType = .integer16AttributeType
    let request : NSFetchRequest<NSDictionary> = NSFetchRequest(entityName: "Odetails")
    request.propertiesToFetch = [description]
    request.resultType = .dictionaryResultType
    do {
        let results = try context.fetch(request)
        return results.isEmpty ? 0 : results[0]["sumSubtotal"] as! Int16
    } catch {
        print(error)
        return 0
    }
}

答案 1 :(得分:1)

而不是强迫展开。您是否可以尝试使用可选绑定来确保正确获取数据。

guard let response: [Odetails] = context.fetch(fetchRequest) else { return 0}
var sum = 0
for res in response {
    sum = sum + Int(res.subtotal)
}
return sum

问题是Int16上有溢出。根据{{​​3}}

  

在大多数情况下,您无需选择特定大小的整数   在你的代码中使用。 Swift提供了一个额外的整数类型Int,   其大小与当前平台的原生单词大小相同:

     

在32位平台上,Int与Int32的大小相同。在64位上   平台,Int与Int64的大小相同。

     

除非您需要使用特定大小的整数,否则请始终使用   Int表示代码中的整数值。这有助于代码的一致性和   互操作性。即使在32位平台上,Int也可以存储任何值   介于-2,147,483,648和2,147,483,647之间,对许多人而言足够大   整数范围。