2012-05-04 17 views
8

Podczas korzystania z typów NSPrivateQueueConcurrencyType i NSMainQueueConcurrencyType dla NSManagedObjectContext, można bezpiecznie zagnieżdżać wywołania performBlock w tym samym kontekście?Zagnieżdżony performBlock: w obiekcie NSManagedObjectContext

[backgroundContext performBlock:^{ 
    NSFetchRequest *myRequest = ...; 
    __block NSArray *result= nil; 
    [backgroundContext performBlockAndWait:^{ 
     results = [backgroundContext executeFetchRequest:myRequest error:NULL]; 
    }]; 
}]; 

To może wydawać się głupie, ale mam istniejący kod źródłowy z wielu pomocników metod enkapsulacji połączenia executeFetchRequest. Nie chcę przyjmować założenia, czy dzwoniący już użył performBlock, czy też nie. Na przykład:

-(void)updateObjects:(BOOL)synchronous 
{ 
    if (YES == synchronous) 
     [self fetchHelper]; 
    else 
    { 
     [backgroundContext performBlock:^{ 
      [self fetchHelper]; 
     }]; 
    } 
} 

-(NSArray*)fetchHelper 
{ 
    [self.backgroundContext performBlockAndWait:^{ 
     //Fetch the objects... 
     [self.backgroundContext executeFetchRequest: (...)]; 
    }]; 
} 

Próbowałem to i to działa. Ale nauczyłem się (na własnej skórze), że bardzo ostrożnie podchodzę do danych podstawowych i wielowątkowości.

Odpowiedz

8

Tak, performBlockAndWait jest powtórką. Bezpośrednio z release notes Apple'a ...

Rdzeń danych formalizuje model współbieżności dla klasy NSManagedObjectContext z nowych opcji. Podczas tworzenia kontekstu można określić wzorzec współbieżności, który będzie z nim używany: zamknięcie wątku, kolejka do wysyłania prywatnego lub główna przesyłka w kolejce. Opcja NSConfinementConcurrencyType zapewnia to samo zachowanie , które było obecne w wersjach systemu iOS przed wersją 5.0 i jest domyślną wartością . Podczas wysyłania wiadomości do kontekstu utworzonego za pomocą powiązania kolejki, należy użyć metody performBlock: lub performBlockAndWait: , jeśli kod nie jest jeszcze wykonywany w tej kolejce (dla typu kolejki głównej ) lub w zakresie operacji performBlock. .. inwokacja (dla typu kolejki prywatnej). W ramach bloków przekazywanych do metod można swobodnie korzystać z metod NSManagedObjectContext. Metoda performBlockAndWait: obsługuje powtarzalność interfejsu API. Metoda performBlock: obejmuje pulę autorelease i wywołuje metodę processPendingChanges po jej zakończeniu.

+0

Co powiesz na performBlock, czy jest to również reentrant? – malhal

+0

Nie jest, jest to uwzględnione w sesji. Twoje żądania zostaną umieszczone w kolejce, jeśli wywołasz funkcję performBlock, ponieważ jest asynchroniczna. –

+0

tylko dla jasności, co robi OP w drugim bicie kodu jest w porządku ?, ale może to spowodować problemy, jeśli obie metody miały "performBlock"? czy to jest właściwy sposób, aby na to spojrzeć? – hokkuk

Powiązane problemy