NSFetchedResultsController在不同的视图控制器互相更新? [英] NSFetchedResultsControllers in different view controllers updating each other?

查看:163
本文介绍了NSFetchedResultsController在不同的视图控制器互相更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ok我越来越普遍的这个问题,因为我注意到了几个滞后在我的应用程序,由于这个。我注意到重排序的问题,但它也发生在其他地方。我有一个CoreDataViewController类,其中所有我的表视图控制器子类。在这个类中,我基本上有所有的NSFetchedResultsController委托方法,因为他们在苹果文档。

Ok I get more and more general with this question, since I've noticed several lags in my app due to this. I've noticed the problem with reordering, but it happens in other places as well. I have a CoreDataViewController class which all my table view controllers subclass. And in this class I basically have all NSFetchedResultsController delegate methods as they are in the apple docs.

然后我试图找出变化注意到这个NSFetchedResultsController以找出我的时间滞后的位置:

Then I've tried to find out how often changes are noticed by this NSFetchedResultsController to find out where my time lag is:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if(self.suspendAutomaticTrackingOfChangesInManagedObjectContext) return;
    NSLog(@"ControllerDidChangeContent");
    TICK;
    [self.tableView endUpdates];
    TOCK;
}

例如在我的视图控制器A中,我有这个获取请求from viewDidLoad):

So for example in my view controller A, I have this fetch request (called from viewDidLoad):

- (void)setupFetchedResultsController
{
    //NSError *error = nil;
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SpendingCategory"];
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"position" ascending:YES]];
    //[self.mainCategory.managedObjectContext executeFetchRequest:request error:&error];
    request.predicate = [NSPredicate predicateWithFormat:@"belongsToMainCategory = %@", self.mainCategory];

    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request
                                                                       managedObjectContext:self.mainCategory.managedObjectContext
                                                                         sectionNameKeyPath:nil
                                                                                  cacheName:nil];
}

如果我在这个视图控制器中改变我的对象的属性,只有一次注释ControllerDidChangeContent,因为它应该。并且是如预期一样快。我的意思是真的只是一个简单的属性更改,只是改变一些数字或字符串等,如:

If I change attributes for my objects in this view controller, my log prints out only once the comment "ControllerDidChangeContent" as it should. And is as fast as expected. And I mean really only a simple attribute change, just changing some number or string etc. such as:

spendingCategory.name = @"Hello world";

如果我已经访问过另一个视图控制器,它在viewDidLoad中设置了NSFetchedResultsController,打印输出两次。这是第二个NSFetchedResultsController:

If however I've already accessed another view controller which setups its NSFetchedResultsController as well in viewDidLoad, my log is printed out twice. Here is the second NSFetchedResultsController:

- (void)setupFetchedResultsController
{
    self.managedObjectContext = ((AppDelegate *)[[UIApplication sharedApplication] delegate]).managedObjectContext;

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SpendingCategory"];

    NSSortDescriptor *mainCatPosition = [[NSSortDescriptor alloc]
                            initWithKey:@"belongsToMainCategory.position" ascending:YES];
    NSSortDescriptor *spendingCatPosition = [[NSSortDescriptor alloc]
                            initWithKey:@"position" ascending:YES];

    request.sortDescriptors = [NSArray arrayWithObjects:mainCatPosition,spendingCatPosition,nil];
    request.predicate = [NSPredicate predicateWithFormat:@"liveBudget = %@", [NSNumber numberWithBool:YES]];

    self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request
                                                                       managedObjectContext:self.managedObjectContext
                                                                         sectionNameKeyPath:@"belongsToMainCategory.position"
                                                                                  cacheName:@"LiveBudget"];

}

我之前提到的简单属性更改需要更长的时间。这是因为现在我的日志打印出两次(!)ControllerDidChangeContent。第一个TICK-TOCK仍然和以前一样快,但第二个接管一秒钟。我想这是因为我有两个NSFetchedResultsController看着同一个实体。

My before mentioned simple attribute change takes way longer. And that's because now my log prints out twice (!) ControllerDidChangeContent. The first TICK-TOCK is still as fast as before, but the second takes over one second. And I guess this is because I have two NSFetchedResultsController watching the same entity.


  1. 问题:
    我还是t很明白为什么他们互相影响?我的意思是确定我更新一个属性在一个视图控制器,所以其他人当然应该注意到这个变化,但为什么两个didChangeContent触发?

  1. Question: I still don't quite understand why they influence each other? I mean ok I update an attribute in one view controller so the other one should of course notice this change, but why are two didChangeContent triggered?

问题:
如何避免?

Question: How can I avoid that? Or how can I improve that?


推荐答案

检查为什么1 [秒]停止之前,转向这个解决方案。
$ $ $ $ $ $我自己,我没有经历这种延迟,在同一上下文中使用多个FRC,所以我的猜测是在其他地方的问题。

I assume it is better to check why the 1[sec] halt before turning to this solution.
myself, I have not experienced that delay when using multiple FRC's on the same context so my guess is the problem lie elsewhere.

您的问题:


  1. FRC正在侦听'NSManagedObjectContextObjectsDid < b>更改通知',因此所有FRC在同一对象的同一上下文上侦听将触发其委托的方法,当这些对象被改变。因此,很清楚为什么您的日志打印了两次(2个不同的FRC已更改其内容)

  1. The FRC is listening for 'NSManagedObjectContextObjectsDidChangeNotification' so all FRC's listening on the same context on the same objects will trigger their delegate's methods when these objects are changed. Hence, it is clear why your log is printed twice (2 different FRC's changed their content)

1 [sec]并应该处理(与仪器检查可以做什么)。正如我所提到的,没有办法避免当在同一上下文中使用FRC时,但是你可以为每个VC创建一个子上下文,使FRC只侦听该子上下文,然后更改将只对其他FRC当你保存上下文链。只要你的VC堆栈不是很深,这不应该是一个真正的问题。在任何情况下,您希望您的其他VC更新更新tableview,以获得流畅的用户体验,所以如果更新花费太长,你应该看到为什么。更多的更改。

1[sec] is a long time for blocking the main thread and should be addressed (check with instruments what can be done). As I mentioned, there is no way to avoid that when using FRC's on the same context, but you can create a child context for each VC you stem an make the FRC listen to that child context only, then changes will only be visible to other FRC when you save down the context chain. as long as your VC stack is not very deep this should not be a real problem. In any case you want your other VC's to get updated with changes as they update the tableview to give a smooth user experience, so if the update take too long you should see why.

这篇关于NSFetchedResultsController在不同的视图控制器互相更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆