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.
Co powiesz na performBlock, czy jest to również reentrant? – malhal
Nie jest, jest to uwzględnione w sesji. Twoje żądania zostaną umieszczone w kolejce, jeśli wywołasz funkcję performBlock, ponieważ jest asynchroniczna. –
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