afterDelay:0有更好的解决方案吗?

时间:2014-03-18 11:11:00

标签: objective-c cocoa-touch cocoa nsobject catransaction

•我的总目标

我的目标是

  1. 在基于视图的表视图中加载一些数据并执行一些操作(用于显示表视图)
  2. 在加载结束时滚动到表视图的顶部。
  3. •更多细节

    在加载过程中,会执行许多操作。更准确地说,表视图是基于视图的,并且在每一行中都有一个文本视图,其内容绑定到某个属性。 实现委托方法- (void)textDidChange:(如有必要,放大文本视图)。 我还为NSTextView创建了子类,并为了同一目的而覆盖了方法- (void)setString:

    因此,当文本加载到表视图的行时,会执行许多操作。

    •代码

    我的代码适用于afterDelay:0(滚动到顶部)但不是没有。

    // works
    - (void)updateTheController
    {
        [super updateTheController] ;
        self.theCollectionView.representedObject = self.representedObject ;
        [self.theCollectionView performSelector:@selector(goToTop) 
                                     withObject:nil 
                                     afterDelay:0] ;
    }
    

    // does not work
    - (void)updateTheController
    {
        [super updateTheController] ;
        self.theCollectionView.representedObject = self.representedObject ;
        [self.theCollectionView goToTop] ;
    }
    

    •我的问题

    我想知道是否有更好的解决方案或解释。我记得CATransaction的内容,但我不知道它是否会在这里工作,我不记得调用哪种方法(以及为什么),[CATransaction commit][CATransaction commit]

    我的问题可能是:我可以替换afterDelay:0,我为什么需要它?

    谢谢!

2 个答案:

答案 0 :(得分:1)

您所经历的工作如何执行命令以及特别是关于KVO的结果在当前的runloop完成后可用。在您的情况下,self.theCollectionView.representedObject = self.representedObject ;的点符号会隐藏setRepresentedObject:的KVO调用,该调用会自动包含在willChangeValueForKey:didChangeValueForKey:个调用中。这可能更好地解释了为什么新的representObject以及新的视图内容在您运行命令时不可用,但仅在runloop完成之后(解释更复杂!)。

因此,使用afterDelay:命令在当前runloop完成后执行,然后才会填充视图并且可以到达顶部。这有时会令人讨厌,因为它似乎打破了逻辑流程。然而,它绝对有效。

答案 1 :(得分:-1)

您可以使用GCD:

- (void)updateTheController
{
    [super updateTheController] ;
    self.theCollectionView.representedObject = self.representedObject;
    dispatch_async(dispatch_get_main_queue(), ^(){
        [self.theCollectionView goToTop];
    });
}

[self.theCollectionView goToTop];将被推入队列并尽快执行。