【问题标题】:Calculating the max value for a core data attribute - NSCFNumber error计算核心数据属性的最大值 - NSCFNumber 错误
【发布时间】:2010-12-28 00:45:11
【问题描述】:

我需要找出核心数据实体的一个属性的最大值。

我仍处于 Cocoa 学习曲线中,这是我用来学习的一个简单的测试应用程序。

该应用程序从文本文件中导入财富并在屏幕上显示一个表格。导入在单独的后台线程中完成。

我在网上找到了这段代码,我试图让它工作:

- (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);  
} 

我的实体名为“Fortune”,属性名为“id”(一个 Double)。

当代码运行时,它会在执行获取请求时崩溃。控制台显示:

2009-12-18 00:53:42.777 FortunesHelperMVC[4027:1703]-[NSCFNumber count]:无法识别的选择器发送到实例 0x1004d7b10 2009-12-18 00:53:42.778 FortunesHelperMVC [4027:1703] 引发了未捕获的异常 2009-12-18 00:53:42.778 FortunesHelperMVC[4027:1703]-[NSCFNumber count]:无法识别的选择器发送到实例 0x1004d7b10 2009-12-18 00:53:42.779 FortunesHelperMVC[4027:1703] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[NSCFNumber 计数]:无法识别的选择器发送到实例 0x1004d7b10” *** 第一次抛出调用堆栈: ( 0 核心基础 0x00007fff83ed9444 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x00007fff85fbb0f3 objc_exception_throw + 45 2核心基础0x00007fff83f321c0 + [NSObject(NSObject)不识别选择器:] + 0 3 核心基础 0x00007fff83eac08f ___转发___ + 751 4 核心基础 0x00007fff83ea81d8 _CF_forwarding_prep_0 + 232 5 基础 0x00007fff88a5609e +[_NSPredicateUtilities max:] + 46 6 基础 0x00007fff8893ce72 -[NSFunctionExpression 表达式ValueWithObject:context:] + 530 7 核心数据 0x00007fff8613b5b1 -[NSMappedObjectStore executeFetchRequest:withContext:] + 2081 8 核心数据 0x00007fff8613ad10 -[NSMappedObjectStore executeRequest:withContext:] + 80 9 核心数据 0x00007fff86108900 -[NSPersistentStoreCoordinator(_NSInternalMethods) 执行请求:withContext:] + 688 10 核心数据 0x00007fff8610621b -[NSManagedObjectContext executeFetchRequest:error:] + 267 11 FortunesHelperMVC 0x0000000100001d9d -[ImportOperation getMaxID] + 572 12 FortunesHelperMVC 0x0000000100001f95 -[ImportOperation main] + 330 13 基础 0x00007fff888f406d -[__NSOperationInternal start] + 681 14 基础 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 ) 在抛出“NSException”实例后调用终止

任何想法为什么这不起作用?在谷歌上搜索了很多之后,我被难住了。

谢谢

达伦。

【问题讨论】:

    标签: objective-c core-data


    【解决方案1】:

    问题是这一行是错误的:

    [fetch setResultType:NSDictionaryResultType];  
    

    结果类型应该是 NSManagedObjectResultType

    问候

    达伦。

    【讨论】:

    • 但这不只是最终返回该类型的所有实体(绕过您设置的 NSExpressionDescription 吗?换句话说,这不会导致中断,但您不会结束收到您正在寻找的财产,对吧?
    【解决方案2】:

    Core Data Programming Guide 的这段代码应该可以工作。

    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"]);
        }
    }
    

    【讨论】:

    【解决方案3】:

    我必须解决一个类似的问题,但处理方式略有不同:

    • 查询实体
    • 按您想要的属性排序
    • 将提取结果限制为 1

    代码如下。我正在查询一个名为“entityName”的实体并检索属性“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];
    }
    

    【讨论】:

    • 当我尝试按照你说的做时,我得到了这个结果。我猜,它给出了 Int32 类型的最大限制。 "account_id" = 139784529;
    • 至少在 iOS 6 和 iOS 7 上,排序时间随着数据库中对象的数量线性增长。坏主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2012-05-10
    • 2016-12-30
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    相关资源
    最近更新 更多