Dov*_*Dov 4 macos cocoa core-data objective-c nsfetchrequest
我有一些核心数据代码精确地遵循Apple的示例代码(获取满足给定函数示例的获取属性值).我正在使用它来获取字段的最大值,所以当我插入该实体类型的下一个对象时,我可以增加它.
我无法让代码工作,直到我将Store Type切换NSXMLStoreType为NSSQLiteStoreType,然后突然间一切似乎都在工作.但事实并非如此.我注意到它总会返回相同的值,即使我插入了较高的对象.但是,在我退出并重新打开(因此数据被持久化并重新读入)之后,它将使用新插入进行更新.
所以我在每次插入后开始提交和保存.在第一次"自动保存"之后,我得到以下错误(连续两次):
- [NSCFNumber count]:无法识别的选择器发送到实例0x100506a20
当我执行一次获取请求时,会发生这种情况(一行两次):
NSArray *objects = [context executeFetchRequest:request error:&error];
Run Code Online (Sandbox Code Playgroud)
更新
我通过Zombies工具运行我的代码,并且能够查看出现错误的对象.运行malloc以分配它的调用是:-[NSUserDefaults(NSUserDefaults) initWithUser:].由于我没有设置任何自己的默认值,我不知道这可能是什么对象.
更新2
我搜索了所有代码中的"发布",并注释掉静态分析器没有抱怨的每一个release或autorelease那个.我仍然有错误.我甚至竟然在我的代码中注释掉每一个release/ autorelease仍然得到它.现在我很确定我自己的代码不会过度释放.
更新3
这篇文章似乎有同样的问题,但他的解决方案没有意义.他将结果类型从更改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:]
Run Code Online (Sandbox Code Playgroud)
我在网上其他地方的许多论坛上都看到了这个问题,但没有人提供可行的解决方案.根据大众的要求,我在下面添加了自己的代码.为了解释一下,我的实体的名称是Box,我试图获得值的Int 32属性是"sortOrder",一个属性.
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;
Run Code Online (Sandbox Code Playgroud)
小智 11
显然,这是一个已知错误,在使用NSInMemoryStoreType数据存储时会发生.它似乎使用NSSQLiteStoreType工作正常.
我为这个错误填写了一份副本 - 我鼓励那些遇到同样问题的人做同样的事情,以增加这种令人讨厌的行为被记录的可能性(甚至更好,修复).