我遇到了一个竞争条件,我不知道如何解决它。 getPurchasedBookTitles和getBookEntryIDs在使用NSOperationQueue的不同线程中,它们互相竞争调用fetchBooks(这是不同类中的方法)。我把managedObjecContext(父,孩子,根)放在锁/解锁的位置,以避免赛车的问题,但似乎并没有解决根本问题。coreData executeFetchRequest方法的竞争条件导致无数据的问题
问题是for-loop中的book.bookTitle(在allBooks中的book * book)会在某些时候变为零,并导致应用程序崩溃或挂起。
在此先感谢!
//在一个单独的类,dispatch_once
- (NSArray *)getPurchasedBookTitles
{
NSMutableArray *bookTitles = [[NSMutableArray alloc] init];
NSArray *allBooks = [[CoreDataManager sharedInstance] fetchBooks];
for (Book *book in allBooks)
{
if (book.bookTitle != nil && book.is_owned != nil)
if (![bookTitles containsObject:book.bookTitle] && [[book is_owned] boolValue] == YES)
[bookTitles addObject:book.bookTitle];
}
return bookTitles;
}
- (NSArray *)getBookEntryIDs
{
NSMutableArray *bookTitles = [[NSMutableArray alloc] init];
NSArray *allBooks = [[CoreDataManager sharedInstance] fetchBooks];
for (Book *book in allBooks)
{
if (book.bookTitle != nil)
if (![bookTitles containsObject:book.bookTitle])
[bookTitles addObject:book.bookTitle];
}
return bookTitles;
}
//在类coreDataManager // managedObjectContextChild,managedObjectContext,writerManagedObjectContext的声明,并在细节的appDelegate和coreDataManager类实例化。
- (NSArray *)fetchBooks
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"bookTitle" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:bookEntity];
[request setPredicate:nil];
[request setSortDescriptors:sortDescriptors];
[managedObjectContextChild lock];
[managedObjectContext lock];
[writerManagedObjectContext lock];
NSError *error = NULL;
NSArray *results = [managedObjectContextChild executeFetchRequest:request error:&error];
if (error != NULL)
NSLog(@"Error fetching - %@", error);
[writerManagedObjectContext unlock];
[managedObjectContext unlock];
[managedObjectContextChild unlock];
return results;
}
感谢您的帮助,但对象Book分别在不同的线程上被提取以供不同的方法使用...... getPurchasedBookTitles和getBookEntryIDs在不同的线程上运行。 – Jerry
是的,这正是问题所在。您从不同线程上的相同受管对象上下文获取相同的Core Data实例,然后在不同线程上使用同一个实例。事实上,你使用不同的线程没有适当的预防措施是整个问题。 –
这是第一个使用managedObjectContext锁定的好主意吗? – Jerry