使用sqrt:function的NSExpression导致NSInvalidArgumentException

时间:2015-05-14 04:22:41

标签: ios core-data nsfetchrequest nsexpression

我收到了NSInvalidArgumentException:

  

***由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'不支持的函数类型传递给SQL存储'

当尝试使用NSExpression获取使用“multiply:by:”函数的嵌套NSExpression的平方根时。

我的代码如下所示:

NSManagedObjectContext *context=[[BDCoreDataController sharedController] mainManagedObjectContext];
NSFetchRequest *theRequest=[[NSFetchRequest alloc] init];

[theRequest setEntity:[NSEntityDescription entityForName:@"BDCompanyEntity" inManagedObjectContext:context]];
theRequest.resultType=NSDictionaryResultType;

NSExpression *constantExpression=[NSExpression expressionForConstantValue:[NSNumber numberWithDouble:22.5]];
NSExpression *firstKeyPath=[NSExpression expressionForKeyPath:@"epsTTM"];
NSExpression *secondKeyPath=[NSExpression expressionForKeyPath:@"bookValuePerShare"];

NSExpression *firstMultiplyExpression=[NSExpression expressionForFunction:@"multiply:by:" arguments:@[firstKeyPath,secondKeyPath]];

NSExpression *secondMultiplyExpression=[NSExpression expressionForFunction:@"multiply:by:" arguments:@[firstMultiplyExpression,constantExpression]];

NSExpression *sqrtExpression=[NSExpression expressionForFunction:@"sqrt:" arguments:@[secondMultiplyExpression]];

NSExpressionDescription *expressionDescription=[[NSExpressionDescription alloc] init];
[expressionDescription setName:@"grahamNumber"];
[expressionDescription setExpression:sqrtExpression];
[expressionDescription setExpressionResultType:NSDoubleAttributeType];

[theRequest setPropertiesToFetch:@[expressionDescription,@"name"]];

NSError *fetchError;
NSArray *grahams=[context executeFetchRequest:theRequest error:&fetchError];

只需尝试评估嵌套的“multiply:by:”就可以使用以下代码执行fetch:

NSManagedObjectContext *context=[[BDCoreDataController sharedController] mainManagedObjectContext];
NSFetchRequest *theRequest=[[NSFetchRequest alloc] init];

[theRequest setEntity:[NSEntityDescription entityForName:@"BDCompanyEntity" inManagedObjectContext:context]];
theRequest.resultType=NSDictionaryResultType;

NSExpression *constantExpression=[NSExpression expressionForConstantValue:[NSNumber numberWithDouble:22.5]];
NSExpression *firstKeyPath=[NSExpression expressionForKeyPath:@"epsTTM"];
NSExpression *secondKeyPath=[NSExpression expressionForKeyPath:@"bookValuePerShare"];

NSExpression *firstMultiplyExpression=[NSExpression expressionForFunction:@"multiply:by:" arguments:@[firstKeyPath,secondKeyPath]];

NSExpression *secondMultiplyExpression=[NSExpression expressionForFunction:@"multiply:by:" arguments:@[firstMultiplyExpression,constantExpression]];

NSExpressionDescription *expressionDescription=[[NSExpressionDescription alloc] init];
[expressionDescription setName:@"grahamNumber"];
[expressionDescription setExpression: secondMultiplyExpression];
[expressionDescription setExpressionResultType:NSDoubleAttributeType];

[theRequest setPropertiesToFetch:@[expressionDescription,@"name"]];

NSError *fetchError;
NSArray *grahams=[context executeFetchRequest:theRequest error:&fetchError];

起初我认为也许“sqrt”NSExpression在嵌套的NSExpression上遇到了麻烦。所以我尝试了一个恒定的NSExpression。以下代码尝试仅计算sqrt NSExpression中的常量。它导致相同的NSInvalidArguementException

NSManagedObjectContext *context=[[BDCoreDataController sharedController] mainManagedObjectContext];
NSFetchRequest *theRequest=[[NSFetchRequest alloc] init];

[theRequest setEntity:[NSEntityDescription entityForName:@"BDCompanyEntity" inManagedObjectContext:context]];
theRequest.resultType=NSDictionaryResultType;

NSExpression *constantExpression=[NSExpression expressionForConstantValue:[NSNumber numberWithDouble:22.5]];

NSExpression *sqrtExpression=[NSExpression expressionForFunction:@"sqrt:" arguments:@[constantExpression]];

NSExpressionDescription *expressionDescription=[[NSExpressionDescription alloc] init];
[expressionDescription setName:@"grahamNumber"];
[expressionDescription setExpression:sqrtExpression];
[expressionDescription setExpressionResultType:NSDoubleAttributeType];

[theRequest setPropertiesToFetch:@[expressionDescription,@"name"]];

NSError *fetchError;
NSArray *grahams=[context executeFetchRequest:theRequest error:&fetchError];

任何可能导致问题的想法?

由于

刀具工

2 个答案:

答案 0 :(得分:3)

在使用SQLite存储时,并非每个对NSExpression有效的表达式在从Core Data获取时都有效。很遗憾,此类用途不支持sqrt:。它可能适用于二进制存储,但是它会失去Core Data的许多优点(例如,它意味着将所有数据一次加载到内存中)。

特别令人讨厌的是,没有文档列表表明支持哪些功能与Core Data一起使用。但错误消息完全正确:尽管此函数对NSExpression有效,但它对SQLite持久性存储无效。

答案 1 :(得分:0)