2012-12-19 6 views
8

Ich habe eine wirklich schlimme Zeit mit diesem Kerndatenfehler.Core Data + 'Anweisung ist noch aktiv'

Meine App und Code funktioniert alles gut, außer gelegentlich beim Aufruf von Anfragen sehr schnell. Es passiert, wenn ich versuche, die App zu brechen. Von einem Bildschirm zum nächsten gehen, Daten herunterladen und Fetch-Anfragen ausführen.

Ich weiß, es hat etwas mit Threading und Core-Daten zu tun.

Ich rufe dieses Stück Code aus einem Hintergrundthread mit seinem eigenen verwalteten Objekt Kontext.

+ (AN_User *)updateWithRecord:(NSDictionary *)record moc:(NSManagedObjectContext *)moc{ 

    NSNumber *userID = nil; 
    NSString *username = nil; 

    if([record objectForKey:@"user_id"]){ 
     userID = [NSNumber numberWithInt:[[record objectForKey:@"user_id"] intValue]]; 
    }else if([record objectForKey:@"id_member"]){ 
     userID = [NSNumber numberWithInt:[[record objectForKey:@"id_member"] intValue]]; 
    } 

    if([record objectForKey:@"username"]){ 
     username = [NSString stringWithFormat:@"%@", [record objectForKey:@"username"]]; 
    }else if([record objectForKey:@"member_name"]){ 
     username = [NSString stringWithFormat:@"%@", [record objectForKey:@"member_name"]]; 
    } 

    if(!userID||!username){ 
     return nil; 
    } 

    __block AN_User *user = nil; 

    [moc performBlockAndWait:^{ 

     NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 

     NSEntityDescription *entity = [NSEntityDescription entityForName:@"AN_User" inManagedObjectContext:moc]; 
     [request setEntity:entity]; 

     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(user_id == %@) OR (username == %@)", userID, username]; 
     [request setPredicate:predicate]; 

     if([moc countForFetchRequest:request error:nil]==0){ 
      user = (AN_User *)[NSEntityDescription insertNewObjectForEntityForName:@"AN_User" inManagedObjectContext:moc]; 
     }else{ 
      NSArray *fetchResults = [moc executeFetchRequest:request error:nil]; 
      if(fetchResults.count>0){ 
       user = [fetchResults objectAtIndex:0]; 
      } 
     } 

     if(user){ 

      user.user_id = userID; 
      user.username = username.lowercaseString; 

      //Parse profile image url 
      NSString *avatar = [record objectForKey:@"avatar"]; 
      NSString *fileName = [record objectForKey:@"filename"]; 
      if([avatar isKindOfClass:[NSString class]]&&avatar.length>0){ 
       user.profile_image_url = [NSString stringWithFormat:@"%@", avatar]; 
      }else if([fileName isKindOfClass:[NSString class]]&&fileName.length>0){ 
       user.profile_image_url = [NSString stringWithFormat:@"http://www.example.com/forum/avs/%@", fileName]; 
      } 

      if([record objectForKey:@"gpbp_respect"]){ 
       user.respect = [NSNumber numberWithFloat:[[record objectForKey:@"gpbp_respect"] floatValue]]; 
      } 

     } 
    }]; 
    return user; 
} 

Ich verstehe es wohl schwer von nur dies zu sagen, aber kann mir jemand sagen, ob ich mit diesen Anfragen tue etwas falsch, dass sofort ersichtlich ist.

+0

[Fügen Sie einen Ausnahmehaltepunkt hinzu] (http://stackoverflow.com/questions/4961770/run-stop-on-objective-c-exception-in-xcode-4). Den Fehler erneut auslösen. Kopieren Sie den Stack-Trace aus dem Debug Navigator und fügen Sie ihn in Ihre Frage ein. –

+0

Danke. Ich habe versucht, dies zu tun, aber ich konnte den Fehler nicht replizieren. Ich denke, ich habe es trotzdem behoben. –

Antwort

6

Wenn Sie in einer Tabelle blättern, die Core-Daten in einem b/g-Thread aufruft, geschieht dies und Core Data erwartet, dass der Kontext in einem Thread enthalten ist.

Ein anderes SO-Poster funktionierte darum, indem ein MOContext pro Thread erstellt wurde, aber ich mag die Idee von CRUD nicht bei mehreren Threads, also habe ich einfach eine dispatch_async (dispatch_get_main_queue(),) -Wrapping-Funktion um meinen Code gelegt. Bis jetzt gibt es keine Abstürze, aber es ist selten, deshalb bin ich mir da nicht absolut sicher.