[ios]无法解析的格式字符串"功能 = = %@"' 使用 NSPredicate 的 predicateWithFormat 时︰

标签: ios Objective-C
发布时间: 2017/3/21 23:06:10
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我想搜索 NSArray 通过 ' function ' 属性。在控制台上打印该数组时的输出如下所示︰

<__NSArrayI 0xa523b40>(
{
    category = "010-T";
    description = "<h3>Opleidingen</h3>";
    function = "T-r";
    name = "Michal Jordan";
    photo = "http://dws.com/34.jpg";
},
{
    category = "010-T";
    description = "abcd";
    function = "AB";
    name = "Pvt MSK";
    photo = "http://test.com/3.jpg";
},
{
    category = "010-T";
    description = "def";
    function = "T-r";
    name = "Sanu M";
    photo = "http://abc.com/1.jpg";
}
)

这段代码,它通过搜索 ' category ',工作︰

NSString *categoryStr = @"010-T";
NSArray *arr = [NSArray arrayWithArray:[myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category == %@",categoryStr]]];

但当我尝试用下面的代码 (通过搜索 function ),引发了一个异常︰

NSString *functionStr = @"T-r";
NSArray *arr = [NSArray arrayWithArray:[myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"function == %@",functionStr]]];

例外情况是︰

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "function == %@"'

这样看来在这里, function 是保留的关键字。

我试过下面的代码,环绕 function 用单引号,但其结果是 arr 有 0 的对象。

NSArray *arr = [NSArray arrayWithArray:[myarr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"'function' == %@",functionStr]]];

在做什么在这里错了?

解决方法 1:

苹果的谓词编程指南指出,"可可中的谓词表达式代表 NSExpression 的实例。请注意, NSExpression 提供了语法,藉以一个可以调用方法通过 FUNCTION 关键字。文档定义的语法为 FUNCTION(receiver, selectorName, arguments, ...) 。虽然我在任何文档中找到对此只字不提,似乎此功能排除文字词的功能在其他上下文中使用。

幸运的是,您可以建立您谓词格式字符串替代方式使用 %K 格式说明符,用于键的名称。例如, [NSPredicate predicateWithFormat:@"%K == %@", @"function", @1] 将不会引发异常,将能正常工作。看到它在行动中的以下代码︰

    NSDictionary *dict1 = @{@"otherKey": @1, @"function" : @2};
    NSDictionary *dict2 = @{@"otherKey": @2, @"function" : @1};
    NSArray *array = @[dict1, dict2];
    NSPredicate *otherKeyPredicate = [NSPredicate predicateWithFormat:@"%K == %@",@"otherKey", @1];
    NSArray *filteredByOtherKey = [array filteredArrayUsingPredicate:otherKeyPredicate];
    NSPredicate *functionPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"function", @1];
    NSArray *filteredByFunction = [array filteredArrayUsingPredicate:functionPredicate];
    NSLog(@"filteredByOtherKey = %@", filteredByOtherKey);
    NSLog(@"filteredByFunction = %@", filteredByFunction);

我们得到下面的输出在控制台上︰

filteredByOtherKey = (
        {
        function = 2;
        otherKey = 1;
    }
)
filteredByFunction = (
        {
        function = 1;
        otherKey = 2;
    }
)

这种方式构建您的谓词可能会略有更多的工作,但是会阻止这些类型的冲突将来。良好做法移动向前是限制格式字符串只包含格式说明符和谓词语法,在运行时完成 prediate 的表达式字符串。

赞助商