2012-05-02 2 views
1

My iOS app зависает, когда я перебираюсь между двумя экранами пару раз. принадлежит для хранения данных, но это просто замерзает без ошибок. У кого-нибудь есть идея, как я могу это исправить?My iOS app зависает при сохранении с mulithreading

self.fetchF = dispatch_queue_create(label, NULL); 
dispatch_async(self.fetchF, ^{ 

    NSArray *feeds = [FeedFetcher getData:self.pageTitle downloadBy:@"up"]; 

    NSManagedObjectContext *newContext = self.managedObject; 

    for (NSDictionary *feedInfo in feeds) { 
     [Feed FeedWithInfo:feedInfo InManageObject:newContext]; 
    } 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     NSError *error = nil; 
     if (newContext != self.managedObject) 
      [newContext save:&error]; 

     if (error) 
      NSLog(@"Error save : %@", error); 

     [self setupFetchedResultsController]; 

     [self downloadImages:feeds]; 
    });   
}); 

Edit:

я изменить свой managedobjectcontext поэтому он имеет каждая нить новое. Но теперь, когда я перехожу между двумя экранами пару раз, он останавливается на [self.fetchedResultsController performFetch: & error]; Без ошибок .. Есть ли у кого-нибудь идеи для решения?

- (void)performFetch 
{ 
    if (self.fetchedResultsController) { 
     if (self.fetchedResultsController.fetchRequest.predicate) { 
      if (self.debug) NSLog(@"[%@ %@] fetching %@ with predicate: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate); 
     } else { 
      if (self.debug) NSLog(@"[%@ %@] fetching all %@ (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName); 
     } 
     NSError *error; 
     if (self.fetchedResultsController != nil) 
      [self.fetchedResultsController performFetch:&error]; 

     if (error) NSLog(@"[%@ %@] %@ (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]); 
    } else { 
     if (self.debug) NSLog(@"[%@ %@] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); 
    } 
    [self.tableView reloadData]; 
} 
+0

Вы уверены, что используете jsut, используя контекст внутри потока, в котором он был создан? – HeikoG

+0

Я создаю его в классе делегата приложения. И я даю его классу, где я должен его использовать. Каждый раз, когда я использую NSManagedObjectContext * newContext = self.managedObject; –

ответ

2

Основные данные, как правило, не являются потокобезопасными. Правило большого пальца - создать NSManagedObjectContext на поток. Я считаю, что вы повторно используете свой контекст среди потоков, и это вызывает проблему.

Docs на параллелизм Ядро данных:

основных данных использует поток (или сериализованную очереди) конфайнмента для защиты управляемых объектов и управляемых контексты объектов (см «Параллелизм с Core Data»). Следствием этого является то, что контекст предполагает, что владелец по умолчанию является потоком или очередью, которая его назначила - это , определяемый потоком, который вызывает его метод init. Вы не должны, , поэтому, инициализируйте контекст в одном потоке, затем передайте его в другой поток. Вместо этого вы должны передать ссылку на постоянный координатор магазина и получить принимающий поток/очередь для создания нового контекста, полученного из этого. Если вы используете NSOperation, вы должны создать контекст в основном (для последовательной очереди) или начать (для параллельной очереди ).

+0

Спасибо, что это работает :) –

Смежные вопросы