无法使 NSPredicate 在自定义 NSObject 上工作

Posted

技术标签:

【中文标题】无法使 NSPredicate 在自定义 NSObject 上工作【英文标题】:Can't make NSPredicate work on custom NSObject 【发布时间】:2014-01-09 14:17:23 【问题描述】:

我有一个名为SCPFLocation 的自定义对象NSSet,我想用每个位置的人类可读格式(名为interpretedForm 的属性)对其进行过滤。以下是我的做法:

NSMutableSet *set = [[SCPFLocation allLocations] mutableCopy];
[set filterUsingPredicate:[NSPredicate predicateWithFormat:@"interpretedForm contains[c] '%@'", searchString]];
self.matches = [set.allObjects sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) 
    return [((SCPFLocation *)obj1).interpretedForm compare:((SCPFLocation *)obj2).interpretedForm];
];

但我不知道为什么这不起作用。在应用谓词过滤器时,set 包含零个对象。我可能做错了什么?

SCPFLocationSCPFValue 的子类,SCPFLocation 继承并覆盖了interpretedForm 属性。下面是SCPFLocation@interface@implementation

@interface SCPFLocation : SCPFValue

@property (strong, nonatomic) NSString *province;
@property (strong, nonatomic) NSString *city;

@end

@implementation SCPFLocation

- (NSString *)interpretedForm

    if (self.city) 
        return [NSString stringWithFormat:@"%@, %@", self.city, self.province];
     else 
        return self.province;
    


@end

还有SCPFValue.h:

@interface SCPFValue : NSObject

/*! The human-readable representation of this @c SCPFValue.
 */
@property (strong, nonatomic) NSString *interpretedForm;

/*! A representation of this @c SCPFValue when it is being passed from and to the API.
 */
@property (strong, nonatomic) NSString *originalForm;

- (id)initWithInterpretedForm:(NSString *)interpretedForm originalForm:(NSString *)originalForm;

@end

【问题讨论】:

【参考方案1】:

您不必像这样在块内投射对象。我觉得这个表格更容易阅读。

NSMutableSet *set = [[SCPFLocation allLocations] mutableCopy];

[set filterUsingPredicate:[NSPredicate predicateWithFormat:@"interpretedForm contains[c] '%@'", searchString]];

self.matches = [set.allObjects sortedArrayUsingComparator:^NSComparisonResult(SCPFLocation *obj1, SCPFLocation *obj2) 
    return [obj1.interpretedForm compare:obj2.interpretedForm];
];

话虽如此。那里没有什么是行不通的。怎么没用?

您能否展示一个无效的对象和搜索字符串的示例。

【讨论】:

感谢关于选角的提示。我很确定谓词是问题所在。 set 使用所有位置对象正确初始化。我还尝试过滤NSStrings 的NSStrings 的NSSet,而不是interpretedForms,然后我创建了谓词@"SELF contains[c] '%@'",它起作用了。我非常想保留一组SCPFLocation 对象。考虑到来自SCPFLocation 的子类化和覆盖的interpretedForm getter,格式是否会出错? 能否请您在interpretedForm方法中设置一个断点以检查该方法是否在过滤期间被调用? 是的,对不起。我先写了答案,但后来意识到我看错了,但后来写了答案,所以我想我会留下它:D 它在过滤过程中被调用。 :(@CarlJ 我刚刚找到了答案。不过,有人可以解释为什么我的解决方案有效吗?【参考方案2】:

我自己想通了,答案很令人沮丧。而不是这样定义谓词:

[NSPredicate predicateWithFormat:@"interpretedForm contains[c] '%@'", searchString]

我是这样做的:

[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"interpretedForm contains[c] '%@'", searchString]]

它成功了。我不知道为什么第一种形式非常遵循 Apple 的Predicate Format String Syntax 时会出现问题。

【讨论】:

嗯...本质上是一回事。格式/字符串只是创建一个字符串。你只是把它推得更远了。你能把 predicateWithFormat 放回去,只是为了三次检查其中的文本吗? 是的,我把它放回没有NSString 的第一个表单,它停止工作。一定是某种ios错误?我正在为 iOS 7 构建。 怎么样 - [NSPredicate predicateWithFormat:@"interpretedForm contains[c] %@", searchString] - 我认为你不需要在 %@ 周围加上单引号 第二种格式可以在没有单引号的情况下使用!它也因双引号而失败。奇怪。 @MattQuiros 根据苹果的说法,如果你使用 predicateWithFormat 它已经用''封装了字符串。 developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…

以上是关于无法使 NSPredicate 在自定义 NSObject 上工作的主要内容,如果未能解决你的问题,请参考以下文章

无法使图表对象在自定义UIView中工作

如何使方法 JSON 可序列化以在自定义 Pyspark 转换器中使用

无法在自定义适配器中将 EditText 转换为 TextView

核心数据:deleteObject 使应用程序崩溃,NSPredicate 是啥原因?

在自定义视图上处理来自 VoiceOver 的“点击”

NSArray中containsObject的用法