objective c - medicion - Cálculo del valor máximo para un atributo de datos centrales-NSCFNumber error
medicion del desarrollo humano (3)
Tuve que resolver un problema similar y abordarlo de forma ligeramente diferente al:
- consultar a la entidad
- ordenar por el atributo que desea
- limitar los resultados de búsqueda a 1
El código para esto está abajo. Estoy consultando una entidad llamada ''entityName'' y recuperando el valor máximo para el atributo ''sequenceId''.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *res = [NSEntityDescription entityForName:@"entityName" inManagedObjectContext:managedObjectContext];
[request setEntity:res];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sequenceId" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
[request setFetchLimit:1];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];
[request release];
if (results == nil) {
NSLog(@"error fetching the results: %@",error);
}
NSInteger maximumValue = 0;
if (results.count == 1) {
Result *result = (Result*)[results objectAtIndex:0];
maximumValue = [result.sequenceId integerValue];
}
Necesito averiguar el valor máximo de un atributo de una entidad de datos central.
Todavía estoy firmemente en la curva de aprendizaje de Cocoa, y esta es una aplicación de prueba simple que estoy usando para aprender.
La aplicación importa fortunas de un archivo de texto y muestra una tabla en la pantalla. Las importaciones se realizan en un hilo de fondo separado.
Encontré este código en línea, que he intentado hacer funcionar:
- (double)getMaxID
{
NSLog(@"in getMaxID"); // debug
// Use a new moc with the original persistentStoreCoordinator to ensure thread safety
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[[self delegate] persistentStoreCoordinator]];
// Create fetch
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
[fetch setEntity:[NSEntityDescription entityForName:@"Fortune" inManagedObjectContext:moc]];
[fetch setResultType:NSDictionaryResultType];
// Expression for Max ID
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"id"];
NSExpression *minExpression = [NSExpression expressionForFunction:@"max:" arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName:@"maxID"];
[expressionDescription setExpression:minExpression];
[expressionDescription setExpressionResultType:NSDoubleAttributeType];
[fetch setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
// Execute the fetch.
double theID = 0;
NSError *error = nil;
NSArray *objects = nil;
objects = [moc executeFetchRequest:fetch error:&error]; // crashes here
if (objects && ([objects count] > 0))
{
NSLog(@"query successful"); // debug
theID = [((NSNumber *)[[objects objectAtIndex:0] valueForKey:@"maxID"]) doubleValue];
}
else
{
NSLog(@"Setting default value for theID"); // debug
theID = 0;
}
return(theID);
}
Mi entidad se llama "Fortuna" y el atributo se llama "id" (un doble).
Cuando el código se ejecuta, falla cuando se ejecuta la solicitud de búsqueda. La consola muestra esto:
2009-12-18 00:53:42.777 FortunesHelperMVC[4027:1703] -[NSCFNumber count]: unrecognized selector sent to instance 0x1004d7b10 2009-12-18 00:53:42.778 FortunesHelperMVC[4027:1703] An uncaught exception was raised 2009-12-18 00:53:42.778 FortunesHelperMVC[4027:1703] -[NSCFNumber count]: unrecognized selector sent to instance 0x1004d7b10 2009-12-18 00:53:42.779 FortunesHelperMVC[4027:1703] *** Terminating app due to uncaught exception ''NSInvalidArgumentException'', reason: ''-[NSCFNumber count]: unrecognized selector sent to instance 0x1004d7b10'' *** Call stack at first throw: ( 0 CoreFoundation 0x00007fff83ed9444 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x00007fff85fbb0f3 objc_exception_throw + 45 2 CoreFoundation 0x00007fff83f321c0 +[NSObject(NSObject) doesNotRecognizeSelector:] + 0 3 CoreFoundation 0x00007fff83eac08f ___forwarding___ + 751 4 CoreFoundation 0x00007fff83ea81d8 _CF_forwarding_prep_0 + 232 5 Foundation 0x00007fff88a5609e +[_NSPredicateUtilities max:] + 46 6 Foundation 0x00007fff8893ce72 -[NSFunctionExpression expressionValueWithObject:context:] + 530 7 CoreData 0x00007fff8613b5b1 -[NSMappedObjectStore executeFetchRequest:withContext:] + 2081 8 CoreData 0x00007fff8613ad10 -[NSMappedObjectStore executeRequest:withContext:] + 80 9 CoreData 0x00007fff86108900 -[NSPersistentStoreCoordinator(_NSInternalMethods) executeRequest:withContext:] + 688 10 CoreData 0x00007fff8610621b -[NSManagedObjectContext executeFetchRequest:error:] + 267 11 FortunesHelperMVC 0x0000000100001d9d -[ImportOperation getMaxID] + 572 12 FortunesHelperMVC 0x0000000100001f95 -[ImportOperation main] + 330 13 Foundation 0x00007fff888f406d -[__NSOperationInternal start] + 681 14 Foundation 0x00007fff888f3d23 ____startOperations_block_invoke_2 + 99 15 libSystem.B.dylib 0x00007fff86a98ce8 _dispatch_call_block_and_release + 15 16 libSystem.B.dylib 0x00007fff86a77279 _dispatch_worker_thread2 + 231 17 libSystem.B.dylib 0x00007fff86a76bb8 _pthread_wqthread + 353 18 libSystem.B.dylib 0x00007fff86a76a55 start_wqthread + 13 ) terminate called after throwing an instance of ''NSException''
¿Alguna idea de por qué esto no está funcionando? Estoy perplejo después de mucho googlear.
Gracias
Darren.
Este código de la Guía de programación de datos básicos debería funcionar.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
[request setEntity:entity];
// Specify that the request should return dictionaries.
[request setResultType:NSDictionaryResultType];
// Create an expression for the key path.
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"creationDate"];
// Create an expression to represent the maximum value at the key path ''creationDate''
NSExpression *maxExpression = [NSExpression expressionForFunction:@"max:" arguments:[NSArray arrayWithObject:keyPathExpression]];
// Create an expression description using the maxExpression and returning a date.
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
// The name is the key that will be used in the dictionary for the return value.
[expressionDescription setName:@"maxDate"];
[expressionDescription setExpression:maxExpression];
[expressionDescription setExpressionResultType:NSDateAttributeType];
// Set the request''s properties to fetch just the property represented by the expressions.
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
// Execute the fetch.
NSError *error = nil;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
if (objects == nil) {
// Handle the error.
}
else {
if ([objects count] > 0) {
NSLog(@"Maximum date: %@", [[objects objectAtIndex:0] valueForKey:@"maxDate"]);
}
}
El problema es que esta línea es incorrecta:
[fetch setResultType:NSDictionaryResultType];
El tipo de resultado debería haber sido NSManagedObjectResultType
Saludos
Darren.