开发者

for loop randomly hanging on executeFetchRequest:error:

I've recently hit a strange problem with my iOS app and have no idea how to go about fixing it.

During first run there's a method that runs in the background which downloads a list of items and item attributes from a game and stores it in Core Data for use in later relationships. The part of the import method which handles the items looks like this:

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 set开发者_开发知识库Value:[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"];
    ...
}

Before this is another loop, which is identical other than dealing with the Attribute entity over SchemaItem and not needing to create any relationships itself, which runs fine.

The problem with this loop is that at random times the loop will hang on [managedObjectContext_ executeFetchRequest:fetch error:nil], I'll get the logged "1" in the console but not the "2" immediately after. What's strange about this, though, is that sometimes the loop will run successfully, no problems.

While it's somewhat nice that the loop runs fine sometimes, it leaves me with no way of knowing what is causing it to hang on executeFetchRequest:error: every other time.

Can anyone here see something I've missed? My head's been fried with it for 2 days now.


Hang, huh?

Sounds like a concurrency issue; your locks are mis-nested. When it hangs, break into the debugger (press the pause button) and look at the backtraces of all threads. More likely than not, you'll find two (or more) threads wedged on a lock.

As Daniel T suggested, you must read the Core Data concurrency guide.

A common mistake is to think that readonly operations are automagically thread safe.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜