NSArray *arrClient = [[NSArray alloc] initWithObjects:@"record 1", @"record 2", nil];
NSArray *arrServer = [[NSArray alloc] initWithObjects:@"record 1", @"record 3", nil];
在arrServer
我想应用谓词来过滤那些不存在的条目arrClient
。例如,在这种情况下record 1
,两个数组中都存在并且应被忽略,因此只应返回一个包含“记录 3”字符串的条目的数组。
这可能吗?
更新
下面的答案很棒。我相信我需要举一个真实的例子来验证我所做的事情是否有意义。(我仍然在下面给出一个紧凑的版本)
现在,clientItems 的类型将是 FTRecord(核心数据)
@interface FTRecord : NSManagedObject
...
@property (nonatomic) NSTimeInterval recordDate;
@end
@implementation FTRecord
...
@dynamic recordDate;
@end
下面的这个类是从 REST 服务解析 json 的持有者。因此,我们前面提到的 serverItems 将属于这种类型。
@interface FTjsonRecord : NSObject <JSONSerializable>
{
}
@property (nonatomic) NSDate *recordDate;
@implementation FTjsonRecord
- (NSUInteger)hash
{
return [[self recordDate] hash];
}
- (BOOL)isEqual:(id)object
{
if ([object isKindOfClass:[FTjsonRecord self]]) {
FTjsonRecord *other = object;
return [[self recordDate] isEqualToDate:[other recordDate]];
}
else if ([object isKindOfClass:[FTRecord self]]) {
FTRecord *other = object;
return [[self recordDate] isEqualToDate:[NSDate dateWithTimeIntervalSinceReferenceDate:[other recordDate]]];
}
else {
return NO;
}
}
以 Wain 为例,这似乎工作正常。现在这可行吗?请记住,serverItems 只是临时的,仅用于与服务器同步,并且将被丢弃。clientItems 是保留的那个。
更新 2:
这次我正在尝试 Manu 的解决方案:
我在我的客户端 DBStore 上创建了这个方法,它由谓词调用。我不能使用的原因containsObject
是因为 serverItems 和 clientItems 中的类类型不是同一类型。
-(BOOL)recordExistsForDate:(NSDate *)date
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"recordDate == %@", date];
NSArray *arr = [allRecords filteredArrayUsingPredicate:predicate];
if (arr && [arr count] > 0) {
return YES;
} else {
return NO;
}
}
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(FTjsonRecord *evaluatedObject, NSDictionary *bindings) {
return ![store recordExistsForDate:[evaluatedObject recordDate]];
}];
NSSet *set = [[serverRecords items] filteredSetUsingPredicate:predicate];
不过,让我担心这个解决方案的是我的 clientItems (allRecords) 的线性读取。我不确定在数组上使用谓词的效率如何,想知道是否有更好的方法来实现这一点。