我最近在我的iOS应用程序中遇到了一个奇怪的问题,并且不知道如何修复它。
在第一次运行期间,有一个在后台运行的方法,该方法从游戏中下载项目和项目属性列表,并将其存储在Core Data中,以便在以后的关系中使用。处理项目的导入方法部分如下所示:
NSManagedObject *item;
for (TFSchemaItem *tfItem in [bs items]) {
item = [NSEntityDescription insertNewObjectForEntityForName:@"SchemaItem" inManagedObjectContext:managedObjectContext_];
NSLog(@"%@", [tfItem itemName]);
[item setValue:[tfItem itemName] forKey:@"itemName"];
[item setValue:[NSNumber numberWithInteger:[tfItem defindex]] forKey:@"defindex"];
[item setValue:[tfItem itemClass] forKey:@"itemClass"];
[item setValue:[tfItem type] forKey:@"itemType"];
[item setValue:[tfItem name] forKey:@"tfName"];
[item setValue:[NSNumber numberWithInteger:[tfItem slot]] forKey:@"itemSlot"];
[item setValue:[NSNumber numberWithInteger:[tfItem quality]] forKey:@"itemQuality"];
[item setValue:[[tfItem imageURL] absoluteString] forKey:@"imageURL"];
[item setValue:[[tfItem largeImageURL] absoluteString] forKey:@"largeImageURL"];
[item setValue:[NSNumber numberWithInteger:[tfItem craftClass]] forKey:@"craftClass"];
[item setValue:[tfItem itemDescription] forKey:@"tfDescription"];
[item setValue:[NSNumber numberWithBool:[tfItem properName]] forKey:@"properName"];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSMutableArray *attrArray = [[NSMutableArray alloc] init];
for (TFItemAttribute *attr in [tfItem attributes]) {
[attrArray addObject:[NSNumber numberWithInt:[attr defindex]]];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"defindex IN %@", attrArray];
[attrArray release];
[fetch setEntity:[NSEntityDescription entityForName:@"Attribute" inManagedObjectContext:managedObjectContext_]];
[fetch setPredicate:predicate];
[fetch setReturnsObjectsAsFaults:NO];
NSLog(@"1");
NSArray *fetchArray = [managedObjectContext_ executeFetchRequest:fetch error:nil];
NSLog(@"2");
[item setValue:[NSSet setWithArray:fetchArray] forKey:@"attributes"];
...
}
在此之前是另一个循环,除了在SchemaItem上处理Attribute实体并且不需要自己创建任何关系之外,它运行正常。
这个循环的问题是,随机时间循环将挂起[managedObjectContext_ executeFetchRequest:fetch error:nil]
,我将在控制台中记录“1”而不是紧随其后的“2”。然而,有些奇怪的是,有时循环会成功运行,没有问题。
虽然循环运行良好有时有点好,但它让我无法知道是什么原因导致它每隔一段时间挂在executeFetchRequest:error:
上。
这里有人能看到我错过的东西吗?我的头已被炒了2天了。
答案 0 :(得分:8)
杭,嗯?
听起来像是并发问题;你的锁是错误的嵌套。当它挂起时,进入调试器(按下暂停按钮)并查看所有线程的回溯。更有可能的是,你会发现两个(或更多)线程楔在锁上。
正如Daniel T所建议的那样,你必须阅读Core Data concurrency guide。
一个常见的错误是认为只读操作是自动线程安全的。