Neuer Thread + NSManagedObjectContext

Ich versuche, meine Anwendungsarbeit zu trennen, wenn eine größere Arbeit zur Leistungsoptimierung erforderlich ist. Mein Problem ist über aNSManagedObjectContext wird in einem anderen Thread als dem Haupt-Thread verwendet.

Ich rufe an:

[NSThread detachNewThreadSelector:@selector(test:) toTarget:self withObject:myObject];

Auf dertest Methode gibt es einige Dinge zu tun und ich habe ein Problem hier:

NSArray *fetchResults = [moc
                         executeFetchRequest:request
                         error:&error];

Hier ist meintest Methode:

-(void) test:(MyObject *)myObject{
  @autoreleasepool {
    //Mycode
  }
}

Daszweite Mal rufe ich die antest Methode, mein neuer Thread wird blockiert, wenn dieexecuteFetchRequest wird genannt. Dieses Problem ist bei mir angekommentest Methode wird mehrmals hintereinander aufgerufen. Ich denke das Problem kommt von dermoc aber ich kann nicht wirklich verstehen warum.

Bearbeiten:

Mit @ Charlies Methode funktioniert es fast. Hier ist mein Code zum Speichern meinerNSManagedObjectContext (Objekt in meinem neuen Thread erstellt).

- (void) saveContext:(NSManagedObjectContext *) moc{
  NSError *error = nil;
  if ([moc hasChanges] && ![moc save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  }
}

Diese Methode wird für den neuen Thread aufgerufen. Mein Problem ist jetzt, dass ich mit diesem Save einen Deadlock habe und nicht wirklich verstehe, warum. Ohne es funktioniert perfekt.

Edit2

Ich arbeite an diesem Problem, kann es aber immer noch nicht beheben. Ich habe meinen Code über das geändertdetachNewThreadSelector. Hier ist mein neuer Code:

NSManagedObjectContext* context = [[NSManagedObjectContext alloc]
                                   initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.persistentStoreCoordinator = self.persistentStoreCoordinator;
context.undoManager = nil;

[context performBlock:^
 {
     CCImages* cachedImage;
     NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
     childContext.parentContext = context;
     cachedImage=[CCImages getCCImageForKey:path inManagedObjectContext:childContext];

     UIImage *image = [self getImageFromCacheWithPath:path andCachedImage:cachedImage atDate:now];
    if (image != nil){
         if(![weakSelf.delegate respondsToSelector:@selector(CacheCacheDidLoadImageFromCache:)])
             [weakSelf setDelegate:appDelegate.callbacksCollector];
         //[weakSelf useCallbackCollectorForDelegate:weakSelf inMethod:@"initPaginatorForListMoments"];
         [weakSelf.delegate CacheCacheDidLoadImageFromCache:image];
     }
}

- (UIImage*) getImageFromCacheWithPath:(NSString*) path andCachedImage:(CCImages *) cachedImage atDate: (NSDate *) now{

  NSURL* localURL=[NSURL URLWithString:cachedImage.path relativeToURL:[self imageCacheDirectory]];

  UIImage * image;
  //restore uiimage from local file system
  if (localURL) {
    image=[UIImage imageWithContentsOfFile:[localURL path]];

    //update cache
    [cachedImage setLastAccessedAt:now];
    [self saveContext];

    if(image)
        return image;
  }
  return nil;

}

Kurz danach speichere ich meine Kontexte (vorerst manuell)

[childContext performBlock:^{
         NSError *error = nil;
         if (![childContext save:&error]) {
             DDLogError(@"Error during context saving when getting image from cache : %@",[error description]);
         }
         else{
             [context performBlock:^{
                 NSError *error = nil;
                 if (![context save:&error]) {
                     DDLogError(@"Error during context saving when getting image from cache : %@",[error description]);
                 }
             }];
         }
     }];

Es gibt ein merkwürdiges Problem. Meine Rückrufmethode wird auf meinem Controller (der das implementiert) problemlos aufgerufenCacheCacheDidLoadImageFromCache: Methode). Auf dieser Methode bestätige ich den Empfang des Bildes (DDLogInfo) und sage, dass ich möchte, dass mein Spinner stoppt. Es erfolgt nicht direkt, sondern erst 15 Sekunden nach dem Aufruf der Callback-Methode.

Mein Hauptproblem ist, dass mein Kontext (ich vermute) immer noch mein Bild aus dem Cache lädt, während es bereits gefunden wurde. Ich sagte 'schon', weil die Rückrufmethode aufgerufen wurde und das Bild vorhanden war. Es liegt keine verdächtige Aktivität der CPU oder des Speichers vor. Instrumente haben kein Leck gefunden.

Ich bin mir ziemlich sicher, dass ich das falsch benutzeNSManagedObjectContext aber ich kann nicht finden, wo.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage