2011-03-11 12 views
7

Estoy tratando de obtener de los registros de Core Data que tienen un startTime entre dos fechas.NSPredicate BETWEEN with NSDate causes - [__ NSDate constantValue]: selector no reconocido enviado a la instancia 0x1e7ff0

Aquí está mi código:

NSDate *today = [NSDate date]; 
NSDate *distantFuture = [NSDate distantFuture]; 

// Create the predicate 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startTime BETWEEN %@", [NSArray arrayWithObjects:today, distantFuture, nil]]; 

NSLog(@"today: %@, distantFuture: %@", today, distantFuture); 
NSLog(@"predicate: %@", predicate); 

// Add the predicate to the fetchRequest 
[[[self fetchedResultsController] fetchRequest] setPredicate:predicate]; 

NSError *error; 
if (![[self fetchedResultsController] performFetch:&error]) 
{ 
    // Update to handle the error appropriately. 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    exit(-1); // Fail 
} 

y aquí está la salida de la consola:

2011-03-11 02:00:03.166 TestApp[2668:307] today: 2011-03-11 01:00:03 AM +0000, distantFuture: 4001-01-01 12:00:00 AM +0000 
2011-03-11 02:00:03.174 TestApp[2668:307] predicate: startTime BETWEEN {2011-03-11 01:00:03 AM +0000, 4001-01-01 12:00:00 AM +0000} 
2011-03-11 02:00:03.180 TestApp[2668:307] -[__NSDate constantValue]: unrecognized selector sent to instance 0x1e7ff0 
2011-03-11 02:00:03.198 TestApp[2668:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDate constantValue]: unrecognized selector sent to instance 0x1e7ff0' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x314d0987 __exceptionPreprocess + 114 
    1 libobjc.A.dylib      0x319a149d objc_exception_throw + 24 
    2 CoreFoundation      0x314d2133 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102 
    3 CoreFoundation      0x31479aa9 ___forwarding___ + 508 
    4 CoreFoundation      0x31479860 _CF_forwarding_prep_0 + 48 
    5 CoreData       0x352ed973 -[NSSQLSimpleWhereIntermediate _generateSQLBetweenStringInContext:] + 766 
    6 CoreData       0x35244fff -[NSSQLSimpleWhereIntermediate generateSQLStringInContext:] + 502 
    7 CoreData       0x35244647 -[NSSQLFetchIntermediate generateSQLStringInContext:] + 74 
    8 CoreData       0x352e42b3 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 234 
    9 CoreData       0x352414ab -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 378 
    10 CoreData       0x35241329 -[NSSQLAdapter newSelectStatementWithFetchRequest:] + 16 
    11 CoreData       0x35241205 -[NSSQLCore newRowsForFetchPlan:] + 288 
    12 CoreData       0x35240531 -[NSSQLCore objectsForFetchRequest:inContext:] + 420 
    13 CoreData       0x35240151 -[NSSQLCore executeRequest:withContext:error:] + 304 
    14 CoreData       0x352d0295 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 896 
    15 CoreData       0x3523d877 -[NSManagedObjectContext executeFetchRequest:error:] + 374 
    16 CoreData       0x352f541b -[NSFetchedResultsController performFetch:] + 766 
    17 TestApp        0x0001ac6d -[MatchesCalendarDataSource loadMatchesFrom:to:delegate:] + 268 
    18 TestApp        0x0001ad51 -[MatchesCalendarDataSource presentingDatesFrom:to:delegate:] + 68 
    19 TestApp        0x00021353 -[KalViewController reloadData] + 110 
    20 TestApp        0x00021b15 -[KalViewController loadView] + 452 
    21 UIKit        0x338dc227 -[UIViewController view] + 30 
    22 UIKit        0x338e8d0b -[UIViewController contentScrollView] + 22 
    23 UIKit        0x338e8b7b -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 30 
    24 UIKit        0x338e8a79 -[UINavigationController _layoutViewController:] + 24 
    25 UIKit        0x338e84d3 -[UINavigationController _startTransition:fromViewController:toViewController:] + 254 
    26 UIKit        0x338e835f -[UINavigationController _startDeferredTransitionIfNeeded] + 182 
    27 UIKit        0x338e82a3 -[UINavigationController viewWillLayoutSubviews] + 14 
    28 UIKit        0x338e823f -[UILayoutContainerView layoutSubviews] + 138 
    29 UIKit        0x338b10cf -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 26 
    30 CoreFoundation      0x3146ebbf -[NSObject(NSObject) performSelector:withObject:] + 22 
    31 QuartzCore       0x30a6c685 -[CALayer layoutSublayers] + 120 
    32 QuartzCore       0x30a6c43d CALayerLayoutIfNeeded + 184 
    33 QuartzCore       0x30a6656d _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 212 
    34 QuartzCore       0x30a66383 _ZN2CA11Transaction6commitEv + 190 
    35 QuartzCore       0x30a89f9d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 52 
    36 CoreFoundation      0x31460c59 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 16 
    37 CoreFoundation      0x31460acd __CFRunLoopDoObservers + 412 
    38 CoreFoundation      0x314580cb __CFRunLoopRun + 854 
    39 CoreFoundation      0x31457c87 CFRunLoopRunSpecific + 230 
    40 CoreFoundation      0x31457b8f CFRunLoopRunInMode + 58 
    41 GraphicsServices     0x35d664ab GSEventRunModal + 114 
    42 GraphicsServices     0x35d66557 GSEventRun + 62 
    43 UIKit        0x338d5329 -[UIApplication _run] + 412 
    44 UIKit        0x338d2e93 UIApplicationMain + 670 
    45 TestApp        0x000029d7 main + 70 
    46 TestApp        0x00002958 start + 52 
) 
terminate called after throwing an instance of 'NSException' 

También he probado el predicado a continuación, que utiliza> = Y < = en lugar de la ENTRE declaración (vea abajo). Esto no causa un error pero tampoco trae ningún registro!

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(startTime >= %@) AND (startTime <= %@)", today, distantFuture]; 

Como prueba de que he intentado un predicado que no incluye objetos NSDate y trabaja muy bien (ver más abajo):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"location.title == %@", @"Boston"]; 

Cualquier ayuda o consejo sería muy apreciado.

Muchas gracias, Mateo


Editar

Gracias por su ayuda de Dave.

Así que ahora vuelvo a usar el constructo <= pero obtengo 0 objetos recuperados.

Solo estaba usando today y distantFuture como prueba para estar absolutamente seguro de que mi hora de inicio estaría entre esas fechas. En el código real es un rango de fromDate a toDate.

Aquí es mi NSPredicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"((%@ <= %K) && (%K <= %@))", fromDate, @"startTime", @"startTime", toDate]; 

Aquí está la salida de la consola:

predicate: CAST(336261600.000000, "NSDate") <= startTime AND startTime <= CAST(339285599.000000, "NSDate") 
[sectionInfo numberOfObjects]: 0 

Estas son las fechas en las que se encuentran en la base de datos (el tipo de atributo se establece en Fecha):

startTime 
--------- 
337249800 
337309200 
337318200 

No tengo idea de por qué se devuelven 0 objetos. ¿Alguien puede ver dónde me estoy equivocando?

Respuesta

4

Tal vez trate de usar y en lugar de & & (aunque su salida de la consola parece mostrar que la conversión correctamente

Me acaba de publicar un ejemplo que funciona para mí, nota que mi condición se da la vuelta, así:

@ "(% K> =% @) Y (% K = <% @)"

Here is the full example

+1

'AND' se analiza exactamente lo mismo que '&&'. –

+0

http://zdam.posterous.com/bye.html – 7wonders

+0

Desafortunadamente ninguno de los enlaces con el dominio zdam.posterous.com parece funcionar – Krystian

24

Según the documentation, los recuentos BETWEEN operador como una expresión agregada, y ...

expresiones de agregado no son compatibles con Core Data.

Así que sí, con el fin de solucionar este problema, debe utilizar la construcción >= y <=.

Sin embargo, dado que una de sus fechas es [NSDate distantFuture], no necesita la comparación "menos que" en absoluto.Usted debe ser capaz de hacer:.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"startTime >= %@", [NSDate date]]; 
+0

Muchas gracias Dave. – mattvick

+3

Sin embargo, todavía tengo el problema de que mi construcción '> =' y '<=' no funciona :-( – mattvick

+0

Parece ser un problema con la tienda SQLite, pero el almacenamiento de memoria admite Entre. – Andy

Cuestiones relacionadas