В моей модели базовых данных есть сущность 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
s, которые должны быть удалены, исходя из следующего условия:
(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
экземпляр.Что не так с предикатом, почему проблема носит спорадический характер и как я могу ее исправить?