- [NSCFNumber count]:无法识别的选择器

时间:2010-12-08 12:28:18

标签: objective-c cocoa macos core-data nsfetchrequest

我有一些核心数据代码严格遵循Apple的sample code提取属性值满足给定函数示例)。我用它来获取字段的最大值,所以当我插入该实体类型的下一个对象时,我可以增加它。

我无法让代码完全正常工作,直到我将商店类型从NSXMLStoreType切换到NSSQLiteStoreType,然后突然间一切似乎都在起作用。但事实并非如此。我注意到它总会返回相同的值,即使我插入了较高的对象。但是,在我退出并重新打开(因此数据被保留并重新读回)之后,它将使用新插入进行更新。

然后我开始在每次插入后提交和保存。在第一次“自动保存”之后,我得到下面的错误(连续两次):

- [NSCFNumber count]:无法识别的选择器发送到实例0x100506a20

当我执行一次获取请求时,会发生这种情况(一行两次):

NSArray *objects = [context executeFetchRequest:request error:&error];

更新

我通过Zombies乐器运行了我的代码,并且能够查看出现错误的对象。运行malloc以分配它的调用是:-[NSUserDefaults(NSUserDefaults) initWithUser:]。由于我没有设置任何自己的默认值,我不知道这可能是什么对象。

更新2

我搜索了所有代码中的“发布”,并注释掉静态分析器没有抱怨的每个releaseautorelease。我仍然有错误。我甚至在我的代码中评论了每个release / autorelease,但仍然得到了它。现在我相当确定我自己的代码不会过度释放。

更新3

This post似乎有同样的问题,但他的解决方案没有意义。他将结果类型从NSDictionaryResultType更改为NSManagedObjectResultType,这会产生不正确的结果。而不是返回单个值(我正在寻找的max,而是返回托管对象上下文中我的实体类的每个对象。

以下是堆栈跟踪的最顶层(当我第一次在异常时中断时):

#0  0x7fff802e00da in objc_exception_throw
#1  0x7fff837d6110 in -[NSObject(NSObject) doesNotRecognizeSelector:]
#2  0x7fff8374e91f in ___forwarding___
#3  0x7fff8374aa68 in __forwarding_prep_0___
#4  0x7fff801ef636 in +[_NSPredicateUtilities max:]
#5  0x7fff800d4a22 in -[NSFunctionExpression expressionValueWithObject:context:]
#6  0x7fff865f2e21 in -[NSMappedObjectStore executeFetchRequest:withContext:]
#7  0x7fff865f2580 in -[NSMappedObjectStore executeRequest:withContext:]

我在网上其他地方的许多论坛上都看到了这个问题,但没有人提供可行的解决方案。根据大众的要求,我在下面添加了自己的代码。为了稍微解释一下,我的实体名称为Box,我试图获取其值的属性是“sortOrder”,Int 32属性。

NSManagedObjectContext *context = [MyLibrary managedObjectContext];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Box"
                               inManagedObjectContext:context]];

// Specify that the request should return dictionaries.
[request setResultType:NSDictionaryResultType];

// Create an expression for the key path.
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"sortOrder"];

// Create an expression to represent the function you want to apply
NSExpression *expression = [NSExpression expressionForFunction:@"max:"
                                                     arguments:[NSArray arrayWithObject:keyPathExpression]];

// Create an expression description using the minExpression 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:@"maxSort"];
[expressionDescription setExpression:expression];
[expressionDescription setExpressionResultType:NSInteger32AttributeType];

// Set the request's properties to fetch just the property represented by the expressions.
[request setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];

// Execute the fetch.
NSError *error;
NSNumber *requestedValue = nil;
NSArray *objects = [context executeFetchRequest:request error:&error];
NSLog( @"objects: %@", objects );
if (objects != nil && [objects count] > 0) {
    requestedValue = [[objects objectAtIndex:0] valueForKey:@"maxSort"];
} else {
    [[NSApplication sharedApplication] presentError:error];
}

[expressionDescription release];
[request release];

NSLog( @"Max Sort Order: %@", requestedValue );
return requestedValue;

6 个答案:

答案 0 :(得分:11)

显然,这是一个已知错误,在使用NSInMemoryStoreType数据存储时会发生。使用NSSQLiteStoreType似乎可以正常工作。

You can find the OpenRadar entry here

我为这个错误填写了副本 - 我鼓励那些遇到相同问题的人也这样做,以增加这种令人讨厌的行为被记录的可能性(甚至更好,修复)。

答案 1 :(得分:3)

当您遇到内存管理问题时(选择器被发送到错误的实例是内存管理问题的一个标志),您可以执行以下操作:

  1. 重新阅读Cocoa memory management rules并确保您关注它们。
  2. 运行static analyser。这通常会占用您忽略内存管理规则的地方。
  3. 尝试使用NSZombieEnabled查看是否[以及何时]向未分配的实例发送邮件。

答案 2 :(得分:1)

-[NSCFNumber count]: unrecognized selector sent to instance 0x100506a20表示您正在调用NSCFNumber对象,但NSCFNumber没有此方法。因此,最有可能的计数是发送到解除分配的NSArray或NSSet对象。

USE NSZombieEnabled = YES。它可能会告诉你,会发生什么。在SO上搜索有关如何设置它的信息。

答案 3 :(得分:1)

如果未正确设置绑定,也会发生这种情况。例如,如果在IB中将矩阵布尔值绑定到“内容”而不是(或除了)“选定标记”,则可能会出现此错误。

如果所有其他方法都失败了,请断开所有绑定并一次重新连接一个,看看哪一个是罪魁祸首。

答案 4 :(得分:0)

在使用完全相同的示例代码遇到完全相同的问题后,在我将[request release] 放入后,它最终为我工作。

答案 5 :(得分:0)

您正在路径表达式中使用密钥路径:sortOrder。至少对于XML-Databases Core-Data 无法处理区分大小写的类型。将您的路径更改为sortorder(全部小写)

如果使用控制器类,您可能会遇到进一步的问题。