2013-04-04 31 views
0

我試圖通過'function'屬性搜索NSArray。當我打印在控制檯上陣列的輸出如下:使用NSPredicate的predicateWithFormat時'無法解析格式字符串'函數==%@「':

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

我在這裏做錯了什麼?

+0

有趣。也許嘗試「self.function == [cd]%@」假設它是一個自定義類的數組。 – Jeremy 2013-04-04 02:42:22

+0

是的,這很有趣,它是一個keyvalue對的數組,而你以後的解決方案給我錯誤如下:無法解析格式字符串「self.function == [cd]%@」,同樣的權利? – 2013-04-04 02:48:14

+0

另一件事,似乎功能是保留字,如果我嘗試使用「名稱」關鍵字,它正在工作.. – 2013-04-04 02:49:09

回答

2

Apple的Predicate Programming Guide指出「可可中的謂詞表達式由NSExpression的實例表示。」請注意,NSExpression提供了一種語法,可以通過FUNCTION關鍵字調用方法調用。 The docs將語法定義爲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的表達式字符串。

+0

是的,這是答案。NSPredicate * predicate = [NSPredicate predicateWithFormat:@「%K like%@」, attributeName,attributeValue]; ,,,謝謝你解決我的問題 – 2013-04-04 06:31:14

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


Here myarr is NSMutableArray. 
Try with this code.