我有一个iPhone应用程序,它需要避免插入重复的记录,起初我以为我可以测试内存数组中的每个对象,为每个对象创建一个提取请求,并测试它是否存在。但这在设备上证明很慢,非常慢(大约5秒,这是不可接受的)。
我一直在尝试将如何创建一些智能谓词拼凑在一起,我可以使用这些谓词来有效地工作,但不会取得太大的成功。
我的对象有一个nsnumber字段,我已将其设置为“标识属性”,而且也是非可选的。此字段称为
sampleTime
(同样,这不是日期,而是一个nsnumber)
以下是我的想法(借用其他线索,甚至我自己的一些问题):
显然,为每个对象(大约380个对象)执行一次获取操作并不能提高性能,所以我觉得我可以在内存中完成大部分操作,而且速度会更快。我需要创建一些使用IN子句的谓词,然后遍历该提取结果,测试是否有任何一个对象在该结果集中,如果没有,则插入它,如果有,则不做任何操作。
但是我的实现没有起作用:
NSMutableArray *timeStampArray = [[NSMutableArray alloc] init];
for (id emTmp in myListOfObjects)
[timeStampArray addObject: [NSNumber numberWithInt:[[emTmp sampleTime] timeIntervalSince1970]]];
NSFetchRequest *fetch = [[[NSFetchRequest alloc] init] autorelease];
[fetch setEntity:[NSEntityDescription entityForName:@"ElectricalMeasurementEntity" inManagedObjectContext:context]];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"sampleTime in %@", timeStampArray]];
NSArray *results = [context executeFetchRequest:fetch error:nil];
int resCount = [results count];
但重新计数总是零,我不知道为什么…
顺便说一句,myListofObjects包含的业务对象也具有nsDate类型的sampleTime属性。
编辑
好的,更新一下,我有基本的工作。之所以没有得到任何结果,是因为创建数组的循环使用了
id
类型,当我使用它时,它没有正确创建nsnumber对象。
现在我这样做:
for (id emTmp in myListOfObjects)
{
Measurement *t = (Measurement*)emTmp;
NSTimeInterval d = [t.sampleTime timeIntervalSince1970];
[timeStampArray addObject: [NSNumber numberWithInt:[[t sampleTime] timeIntervalSince1970]]];
}
它创建了一个很好的列表,效果很好。
然而,我接下来要做的是:
NSMutableArray *itemsToInsert = [[NSMutableArray alloc] init];
for (id em in myListOfObjects)
{
BOOL found = NO;
Measurement *t = (Measurement*)em;
for (id e in results) //results from Fetch Request which is now populated properly
{
MeasurementEntity *entity = (MeasurementEntity*)e;
if ([entity.sampleTime isEqualToNumber:[NSNumber numberWithInt:[[t sampleTime] timeIntervalSince1970]]])
{
found = YES;
break;
}
}
if (!found)
[itemsToInsert addObject: t];
}
这个循环(对于大约850个对象,在iPhone3GS上)大约需要10-12秒,我可以理解为什么(当850*850=722500个循环!)我能提高效率吗?
谢谢