1

我创建了 NSManagedObject 的类别,例如createcount等。除了以下之外,所有这些都可以找到

@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 == "tar.tw45@gmail.com"

你知道是什么原因造成的吗?欢迎任何意见或建议:)

4

1 回答 1

2

我假设您忘记了问题代码中的引号(正如@kitschmaster 在他的评论中所说),并且代码实际上如下所示:

NSString *email = @"tar.tw45@gmail.com";
// Case 1:
NSLog(@"%@", [User findWithPredicate:@"email == '%@'", email]);
// Case 2:
NSLog(@"%@", [User findWithPredicate:[NSString stringWithFormat:@"email == '%@'", email]]);

在情况 (1)中,您的实用程序方法会创建以下谓词

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

由于引号,此谓词搜索逐字字符串。 "%@"如果删除引号:

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

然后它可以正常工作。

在情况 (2) 中,您的实用程序方法创建谓词

[NSPredicate predicateWithFormat:@"email == 'tar.tw45@gmail.com'"];

因为它是使用已经格式化的查询字符串调用的。这在这种特殊情况下有效。但如果查询本身包含任何引号,它将失败。例如:

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

工作正常,但

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

崩溃。创建谓词时,通常应避免使用。stringWithFormat

总结:如果你在格式字符串中省略引号,第一个版本可以正常工作。不应使用第二个版本。

于 2013-02-09T10:05:07.267 回答