NSExpression 使用 sqrt: 函数导致 NSInvalidArgumentException

NSExpression using sqrt: function results in NSInvalidArgumentException

我收到一个 NSInvalidArgumentException:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unsupported function type passed to SQL store'

当尝试使用 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:" 来执行提取,此代码可以正常工作:

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

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

谢谢

工具人

sqrt: 函数似乎在 OS X v10.5 上可用,但在 iOS.

上不可用

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

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

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