无法使 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
包含零个对象。我可能做错了什么?
SCPFLocation
是SCPFValue
的子类,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
使用所有位置对象正确初始化。我还尝试过滤NSString
s 的NSString
s 的NSSet
,而不是interpretedForm
s,然后我创建了谓词@"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 上工作的主要内容,如果未能解决你的问题,请参考以下文章
如何使方法 JSON 可序列化以在自定义 Pyspark 转换器中使用
无法在自定义适配器中将 EditText 转换为 TextView