0

我在我的应用程序中有一个名为​​的方法,这是我的视图控制器中最重要的部分。在该方法中我做了几个显着性的东西(下载,分析,保存到永久存储),所以它会更容易让你看看:当我开始收集数据下载,保存和重新加载UITableView阻止UI

-(void)collectData 
{ 
    // Downloading all groups and saving them to Core Data 
    [[AFHTTPRequestOperationManager manager] GET:ALL_GROUPS parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     NSMutableDictionary* groups = [NSMutableDictionary new]; 
     NSMutableArray* newIds = [NSMutableArray new]; 
     NSError *error; 

     // Saving everything from response to MOC 
     for (id group in responseObject) { 
      Group *groupEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Group" inManagedObjectContext:self.moc]; 

      groupEntity.name = [group valueForKey:@"name"]; 
      groupEntity.cashID = [group valueForKey:@"id"]; 
      groupEntity.caseInsensitiveName = [[group valueForKey:@"name"] lowercaseString]; 
      groupEntity.selected = @NO; 

      // Filling up helping variables 
      groups[groupEntity.cashID] = groupEntity; 
      [newIds addObject:groupEntity.cashID]; 
     } 

     // Fetching existing groups from Persistant store 
     NSFetchRequest* r = [NSFetchRequest fetchRequestWithEntityName:@"Group"]; 
     [r setIncludesPendingChanges:NO]; 
     r.predicate = [NSPredicate predicateWithFormat:@"cashID IN %@",newIds]; 
     NSArray *existingGroups = [self.moc executeFetchRequest:r error:&error]; 

     // Deleting groups which already are in database 
     for (Group* g in existingGroups) { 
      Group* newGroup = groups[g.cashID]; 
      g.name = [newGroup valueForKey:@"name"]; 
      g.cashID = [newGroup valueForKey:@"cashID"]; 
      g.caseInsensitiveName = [[newGroup valueForKey:@"name"] lowercaseString]; 
      [self.moc deleteObject:newGroup]; 
     } 

     // Saving Entity modification date and setting it to pull to refresh 
     [self saveModificationDate:[NSDate date] forEntityNamed:@"Group"]; 
     [self.pullToRefreshView.contentView setLastUpdatedAt:[self getModificationDateForEntityNamed:@"Group"] 
             withPullToRefreshView:self.pullToRefreshView]; 

     // Save groups to presistant store 
     if (![self.moc save:&error]) { 
      NSLog(@"Couldn't save: %@", [error localizedDescription]); 
     } 

     [[self fetchedResultsController] performFetch:&error]; 
     [self.pullToRefreshView finishLoading]; 
     [self.tableView reloadData]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     // Show alert with info about internet connection 
     [self.pullToRefreshView finishLoading]; 
     UIAlertView *internetAlert = [[UIAlertView alloc] initWithTitle:@"Ups!" message:@"Wygląda na to, że nie masz połączenia z internetem" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 
     [internetAlert show]; 
    }]; 
} 

所以(第一次运行或推动刷新)此方法阻止了用户界面。 我想要避免这种情况,但是当我将success块放入另一个dispatch_async并返回到主队列时,只有[self.tableView reloadData]我面临保存到持久性存储或其他索引不良的问题。

我该如何在背景中做这件事,让UI响应用户?

+1

看看这个示例应用程序,它包含一个背景加载器方法。请注意,您必须使用自己的managedObjectContext创建后台线程,并且需要注册MOC通知,然后合并主MOC(主线程)中的更改。看看代码,如果你有特定的问题发布。 http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/ –

+0

现在我已经添加了一些日志和我看到'[self.moc保存:&错误]'是封锁所有内容,并且速度很慢...我认为这是问题... – cojoj

回答

0

只是一个想法,试试用dispatch_sync。看看this explanation这里日志结果类似于你的需要。在同步块后放[yourTableView reloadData]

希望它有帮助!

+0

不幸的是,仍然阻止了用户界面。当它被阻止时,我可以刷卡,并且在它被解除封锁后,我被移到这个地方。 – cojoj

+0

您是否尝试过两种调度功能的组合?一个用于成功块,另一个用于重新加载数据? – NeverHopeless

+0

是的......当我拉动刷新后UI正在被阻塞,所以我认为我必须把这个整个核心数据保存到另一个队列中,但没有任何反应! – cojoj

0

看起来AFNetwork调用不是异步的,所以试着通过performselector调用你的方法。