0

我得到一个 NSInvalidArgumentException:

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

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

我的代码如下所示:

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:”来执行提取可以很好地使用以下代码:

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];

任何想法可能导致问题?

谢谢

工具人

4

2 回答 2

3

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

特别令人讨厌的是,没有记录的列表表明哪些函数支持与 Core Data 一起使用。但是错误消息是完全正确的:虽然这个函数对使用有效NSExpression,但对 SQLite 持久存储无效。

于 2015-05-14T17:34:16.407 回答
0

sqrt:自 v10.5 起,该功能似乎在 OS X 上可用,但在 iOS 上不可用。

请参阅文档:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSExpression_Class/index.html#//apple_ref/occ/clm/NSExpression/expressionForFunction:arguments:

于 2015-05-14T06:32:31.540 回答