我的问题如下:我的UI中有三个按钮,它们将使用不同的参数触发相同的提取请求。如果我按顺序按这些按钮,但每次之间等待一两秒钟,则一切正常。如果我做得更快,该应用程序将冻结。调试器显示了一个互斥锁。现在,我将CoreData与mainMOC和backgroundMOC一起使用,但找不到我做错了什么以及如何解决问题。
我已经检查了类似的问题,但是建议的所有解决方案都不适用于我。
这是我认为涉及此问题的代码:
@interface LooksDataSource ()
@property (nonatomic,strong) NSManagedObjectContext *mainContext;
@property (nonatomic,strong) NSManagedObjectContext *backgroundContext;
@property (nonatomic,strong) NSFetchedResultsController *fetchedResultsController;
@end
@implementation LooksDataSource
-(id) init {
@throw [NSException exceptionWithName:@"LooksDataSource exception" reason:@"please use initWithManagedObjectContext" userInfo:nil];
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(id) initWithManagedObjectContext: (NSManagedObjectContext *) context {
self = [super init];
if (self) {
self.mainContext = context;
dispatch_async(dispatch_get_global_queue(0, 0), ^(){
self.backgroundContext = [[NSManagedObjectContext alloc] init];
self.backgroundContext.persistentStoreCoordinator = self.mainContext.persistentStoreCoordinator;
});
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(repoUpdated:) name:NSManagedObjectContextDidSaveNotification object:self.mainContext];
}
return self;
}
-(void) findLooksWithPredicate: (NSPredicate *) predicate {
if (![predicate isEqual:self.fetchedResultsController.fetchRequest.predicate]) {
[self performNewRequestwithPredicate:predicate];
}
else {
//return results of latest fetch
id <NSFetchedResultsSectionInfo> sectionZeroInfo = [self.fetchedResultsController sections][0];
NSMutableArray *objectIDsForResults = [NSMutableArray array];
for (NSManagedObject *aResult in [sectionZeroInfo objects]) {
[objectIDsForResults addObject:aResult.objectID];
}
dispatch_async(dispatch_get_main_queue(), ^{
//re-create the MOs referred to in objectIDsForResults in the "main" MOC
NSMutableArray *resultsOnMainMOC = [NSMutableArray array];
for (NSManagedObjectID *aResultID in objectIDsForResults) {
[resultsOnMainMOC addObject:[self.mainContext objectWithID:aResultID]];
}
NSArray *results = [NSArray arrayWithArray:resultsOnMainMOC];
[self.delegate looksDataSource:self
returnedResults:results];
});
}
}
感谢你的帮助
最佳答案
正如@Wain所说,目前尚不清楚您如何在此处使用线程以及在何处进行后台获取。
话虽如此 ...
创建后台MOC的方法不是线程安全的:
您创建使用线程限制并发类型的托管对象上下文。
这意味着您只能在创建该线程的线程上使用此上下文。
由于您使用GCD创建此上下文,因此您不知道是哪个线程创建了该上下文,也无法使该线程保持活动状态。
问题的解决方案是@Wain所说的:对于在后台分派的每个操作,创建一个受限的受管对象上下文,使用它,并在操作结束时确保将其处置:
dispatch_async(dispatch_get_global_queue(0, 0), ^(){
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = self.mainContext.persistentStoreCoordinator;
//Make the fetch and export results to main thread
});
关于ios - 多个提取请求导致应用程序卡住,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21800861/