1

我創建NSManagedObject的類別,如創建創建計數和其他人。所有這些作品發現,除了以下NSPredicate與格式的va_list/NSArray的失敗,但成功的字符串

@interface NSManagedObject(ManagedObjectExtension) 
+ (id)findWithPredicate:(id)stringOrPredicate, ...; 
@end 

@implementation NSManagedObject(ManagedObjectUtilities) 

+ (id)findWithPredicate:(id)stringOrPredicate, ... { 
    NSFetchRequest *fetchRequest = [self allFetchRequest]; 
    if (stringOrPredicate) { 
     NSPredicate *predicate; 
     if ([stringOrPredicate isKindOfClass:[NSString class]]) { 
      va_list variadicArguments; 
      va_start(variadicArguments, stringOrPredicate); 
      predicate = [NSPredicate predicateWithFormat:stringOrPredicate arguments:variadicArguments]; 
      va_end(variadicArguments); 
     } else { 
      predicate = (NSPredicate *)stringOrPredicate; 
     } 
     [fetchRequest setPredicate:predicate]; 
    } 


    NSError *error; 
    NSArray *results = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error]; 

    if (error) { 
     NSLog(@"%@", [error description]); 
    } 

    if ([results count] == 0) { 
     return nil; 
    } else if ([results count] == 1) { 
     return [results objectAtIndex:0]; 
    } else { 
     return results; 
    } 
} 

@end 

而這些結果

NSString *email = [NSString stringWithString:someTextField.text]; 
NSLog(@"%@", [User findWithPredicate:@"email == "%@", email]); 
==> (null) 
NSLog(@"%@", [User findWithPredicate:[NSString stringWithFormat:@"email == "%@", email]]); 
==> "<User: 0x1d827e10> ..." 

基本上,當我發送一個字符串,而不是格式化字符串和參數的這種方法僅適用。如果我打印在此方法內創建的謂詞,這些結果是

[User findWithPredicate:@"email == "%@", email]; 
==> email == "%@" 
[User findWithPredicate:[NSString stringWithFormat:@"email == "%@", email]]; 
==> email == "[email protected]" 

你知道什麼會導致這種情況嗎?任何意見或建議,歡迎:)

+1

這是一個錯字:@「email ==」%@「 應該是:@」email =='%@'「 – kitschmaster 2013-02-09 07:49:12

+0

@kitschmaster謝謝,這很簡單,因爲刪除單引號可以解決問題。 – 2013-02-10 16:51:37

回答

2

我以爲你忘了你的問題的代碼引號(如@kitschmaster在他的評論中說的),並且該代碼實際上是這樣的:

NSString *email = @"[email protected]"; 
// Case 1: 
NSLog(@"%@", [User findWithPredicate:@"email == '%@'", email]); 
// Case 2: 
NSLog(@"%@", [User findWithPredicate:[NSString stringWithFormat:@"email == '%@'", email]]); 

在情況(1),你的效用方法創建以下謂詞

[NSPredicate predicateWithFormat:@"email == '%@'", email]; 

和這個謂詞搜索該verbat im string"%@"因爲有引號。如果刪除引號:

NSLog(@"%@", [User findWithPredicate:@"email == %@", email]); 

然後它工作正常。

在情況(2),您的實用方法創建謂詞

[NSPredicate predicateWithFormat:@"email == '[email protected]'"]; 

,因爲它被稱爲與已格式化的查詢字符串。這在這個特定情況下起作用。但是如果查詢本身包含任何引號就會失敗。例如:

[User findWithPredicate:@"name == %@", @"a'b"] 

工作正常,但

[User findWithPredicate:[NSString stringWithFormat:@"name == '%@'", @"a'b"]] 

崩潰。 創建謂詞時通常應避免使用stringWithFormat

摘要:第一個版本可以正常工作,如果你省略引號的格式字符串。不應該使用第二個版本。

+0

謝謝,從格式字符串中刪除單引號修復問題,我會牢記這一點:) – 2013-02-10 16:52:25

相關問題