使用谓词和日期计算的核心数据获取有时会崩溃

时间:2018-10-03 18:33:38

标签: ios core-data nspredicate nsfetchrequest

我的核心数据模型中有一个ResponseCacheRecord实体,具有以下属性(以及其他一些属性):

  • removeWhenExpired(非可选布尔值)
  • timestamp(非可选日期)
  • validDuration(非可选的Double)

托管对象如下:

extension ResponseCacheRecord {
    @NSManaged var identifier: String
    @NSManaged var timestamp: Date
    @NSManaged var validDuration: TimeInterval
    @NSManaged var removeWhenExpired: Bool
    // ...
}

class ResponseCacheRecord: NSManagedObject {

    @objc var expired: Bool {
        let age =  Date().timeIntervalSince(timestamp)
        return age > validDuration
    }

    override func awakeFromInsert() {
        super.awakeFromInsert()
        timestamp = Date()
    }
}

我已经写了一个提取请求,以根据以下条件返回应删除的所有过期ResponseCacheRecord

(removeWhenExpired == true) && (timestamp < Date() - validDuration)

获取内容如下:

let request = NSFetchRequest<ResponseCacheRecord>(entityName: "ResponseCacheRecord")
request.predicate = NSPredicate(format: "(removeWhenExpired == YES) AND (timestamp < (CAST(%@, 'NSNumber') - validDuration))", NSDate())    
do {
    let expiredRecords = try `default`.managedObjectContext.fetch(request)
} catch {
    // Error handling...
}

但是我们收到了一些崩溃报告,指出了在调用fetch(_:)期间出现的问题:

Fatal Exception: NSInvalidArgumentException
-[__NSCFNumber timeIntervalSinceReferenceDate]: unrecognized selector sent to instance 0x1cc0287e0

Fatal Exception: NSInvalidArgumentException
0  CoreFoundation                 0x18489ad8c __exceptionPreprocess
1  libobjc.A.dylib                0x183a545ec objc_exception_throw
2  CoreFoundation                 0x1848a8098 __methodDescriptionForSelector
3  CoreFoundation                 0x1848a05c8 ___forwarding___
4  CoreFoundation                 0x18478641c _CF_forwarding_prep_0
5  CoreFoundation                 0x1847ac580 -[NSDate compare:]
6  Foundation                     0x18534ca2c -[NSComparisonPredicateOperator performPrimitiveOperationUsingObject:andObject:]
7  Foundation                     0x1851f7548 -[NSComparisonPredicate evaluateWithObject:substitutionVariables:]
8  Foundation                     0x1851ff118 -[NSCompoundPredicateOperator evaluatePredicates:withObject:substitutionVariables:]
9  Foundation                     0x1851fee68 -[NSCompoundPredicate evaluateWithObject:substitutionVariables:]
10 CoreData                       0x18717f4ec -[NSManagedObjectContext executeFetchRequest:error:]
11 CoreData                       0x1872493e0 -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:]
12 CoreData                       0x187249bbc __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke
13 CoreData                       0x18724be10 internalBlockToNSManagedObjectContextPerform
14 libdispatch.dylib              0x18418ca60 _dispatch_client_callout
15 libdispatch.dylib              0x1841c9ed4 _dispatch_queue_barrier_sync_invoke_and_complete
16 CoreData                       0x1872383b4 _perform
17 CoreData                       0x1872498b0 -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]
18 CoreData                       0x18717ec30 -[NSManagedObjectContext executeFetchRequest:error:]
19 libswiftCoreData.dylib         0x1037dae68 NSManagedObjectContext.fetch<A where ...> (NSFetchRequest<A>) throws -> [A] (__hidden#48_:18)
20 <redacted>                     0x103293c4c specialized static ResponseCache.evictExpiredRecordsIfNecessary() -> () (ResponseCache.swift:228)

因此,谓词似乎有问题,并且实际上在NSDate实例上调用了NSNumber选择器。谓词有什么问题,为什么这个问题是偶发性的,我该如何解决?

0 个答案:

没有答案