CALayer Live调整了糟糕的表现

时间:2011-11-28 11:48:08

标签: macos calayer catransaction

我有一个用户界面,其中NSCollectionViewItem的视图内容是通过CALayers以编程方式绘制的。我在调整大小时使用CAConstraintLayoutManager来保持子层的布局一致,但是这样做时我的表现非常糟糕。似乎调整窗口大小,导致调整两个CATextLayer的大小以使它们适合根层的宽度,并重新定位一个CATextLayer以使其保持右对齐,从而导致应用程序花大部分时间执行CGSScanConvolveAndIntegrateRGB功能(我使用过Time Profiler仪器)。

最“昂贵”的图层(即使是显示的唯一图片也会造成最多的结果)是一条包裹的多线CATextLayer。我完全不知道如何获得更好的性能(我已经尝试过不使用CAConstraintLayoutManager并使用图层对齐,但我得到了同样的东西)。有谁有这个问题?有办法吗?

PS:我已经将布局管理器子类化,并在执行- (void)layoutSublayersOfLayer:(CALayer *)layer期间禁用了所有动画,方法是在kCATransactionDisableActions中设置为CATransaction,但似乎没有帮助。

编辑:我已经为文本图层禁用了字体平滑,性能提升了一点点(非常少),但它在_ZL9view_drawP7_CAViewdPK11CVTimeStampb中花费了大量时间(这是被调用的东西)我认为,通过ATI Radeon驱动程序的一个主题。

1 个答案:

答案 0 :(得分:1)

我解决了。的种类。它对我来说似乎仍然是一个肮脏的黑客,但我无法找到如何使setNeedsDisplayInRect工作,所以我最终这样做:

  1. 在NSWindow代表:

    - (void)windowWillStartLiveResize:(NSNotification *)通知 {     [[NSNotificationCenter defaultCenter] postNotificationName:@" beginResize"对象:无]; }

    - (void)windowDidEndLiveResize:(NSNotification *)通知 {     [[NSNotificationCenter defaultCenter] postNotificationName:@" endResize"对象:无];
    }

  2. 在我的自定义视图中,这两个通知分别称为-(void)beginResize-(void)endResize选择器。第一个将BOOL inLiveResize变量设置为YES,而第二个将其设置为NO并再次使用新帧大小调用setFrameSize。

  3. 我覆盖了(被覆盖?不是母语为英语的人,对不起)这样的-(void)setFrameSize:(NSSize)newSize方法:

    -(void)setFrameSize:(NSSize)newSize 
    {        
        if (inLiveResize) {
            NSRect scrollFrame = [[[self superview] enclosingScrollView] documentVisibleRect];
    
            BOOL condition1 = (self.frame.origin.y > (scrollFrame.origin.y - self.frame.size.height));
            BOOL condition2 = (self.frame.origin.y < (scrollFrame.origin.y + scrollFrame.size.height + self.frame.size.height));
    
            if (condition1 && condition2)
                [super setFrameSize:newSize];
        }
        else {
            [super setFrameSize:newSize]; }}
    
  4. 那就是它。这样,只有可见视图会随窗口一起调整大小,而其他视图会在操作结束时重新绘制。它有效,但我不喜欢肮脏的&#39;是的,我确信使用setNeedsDisplayInRect方法可以实现更优雅,内置(ish)的方法。我会研究更多。