我的目标是
在加载过程中,会执行许多操作。更准确地说,表视图是基于视图的,并且在每一行中都有一个文本视图,其内容绑定到某个属性。
实现委托方法- (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
,我为什么需要它?
谢谢!
答案 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];
将被推入队列并尽快执行。