使用 NSPredicate 過濾數組時,硬編碼字符串常量正常,但使用變量 NSString *user = @"Joe"; 時查詢失敗。
NSString *user = @"Joe";
// 錯誤:謂詞格式字符串中直接寫變量名,不會被解析
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == user", @"id"];
%K 是鍵路徑佔位符,但 user 在格式字符串中被視為字面量鍵名,而非變量值。
NSString *user = @"Joe";
// 正確:%@ 代表對象值,自動處理引號、轉義
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"id", user];
NSArray *filtered = [usersInfo filteredArrayUsingPredicate:predicate];
| 佔位符 | 含義 | 適用類型 |
|---|---|---|
%@ | 對象描述 (調用 description) | NSString, NSNumber, NSDate, 自定義對象等 |
%K | 鍵路徑 / 屬性名 | NSString (作為屬性名) |
%d, %i | 整數 | int, NSInteger |
%f | 浮點數 | float, double, CGFloat |
%ld | 長整數 | long, long long |
// 多條件組合
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@ AND %K > %@",
@"name", userName, @"age", @(18)];
// 包含關係 (類似 SQL LIKE)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS[cd] %@", @"name", searchText];
// [cd] = 不區分大小寫 + 不區分重音
// 集合操作
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K IN %@", @"status", @[@"active", @"pending"]];
// 正則表達式
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K MATCHES %@", @"email", @"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$"];
若謂詞格式本身需動態生成:
NSString *key = @"id";
NSString *value = @"Joe";
NSString *format = [NSString stringWithFormat:@"%%K == %%@", key]; // 雙 %% 轉義為單 %
NSPredicate *predicate = [NSPredicate predicateWithFormat:format, value];
但**強烈建議直接使用第一種參數化方式**,避免格式字符串注入風險與轉義錯誤。
NSPredicate predicateWithFormat: 採用參數化綁定機制,**值類參數必須用 %@**,鍵名參數用 %K。切勿在格式字符串中直接拼接變量名,這是導致查詢失效的常見原因。