我有一个有趣的案例。 并且需要帮助。

我的Mac应用程序具有一个层托管的NSView,其中包含许多层,子层和子子层。想象一下一个带有项目(图标,文本标签)的Finder窗口……类似的东西。每个项目都有一个按钮,即选择背景层。

一切都很好,直到您拥有1000个这些物品为止。

现在有了很多这些项目,当我尝试与此 View 进行交互时,我的应用程序将无响应。而且棘手的是,不是我的应用消耗了CPU,而是WindowServer。达到100%,系统卡住了一段时间。

重要说明:

我的观点是应用界面的一部分。有一个带有其他 View 的主窗口。他们也有自己的结构。

而且我注意到,如果将这个层托管的 View 放到一个单独的窗口中,它可以很好地工作,并且不会卡住具有相同1000个项目的对象。但是,如果我将其放回主窗口,它将开始停止系统。

问题

  • 我的应用程序( View /图层)是什么使WindowServer发疯?
  • 为什么将此 View 放置到单独的窗口有帮助?

  • 我已经进行了一些测试,并删除了每个项目的所有子层,而每个仅剩下一两个。它减少了系统的负载,但仍然很糟糕。我已经禁用了所有图纸-只是图标的小图像。也没有帮助。

    最佳答案

    WindowServer的主要工作是为macOS绘制与图形相关的事物,这意味着您可以从整个屏幕上看到所有内容,您必须仔细阅读WindowServer并为您绘制图形。

    WindowServer使用高CPU的原因很多。

  • 您的应用程序中有复杂的绘制方法。 -尝试简化绘制方法。
  • 桌面上有很多图形,因此WindowServer不仅可以绘制应用程序,还可以绘制桌面图形。 -尝试清理您的桌面。
  • 您打开了一些需要复杂图形绘制的应用程序吗? -尝试关闭该应用程序。

  • 在看到确切的代码之前,我无法告诉您为什么将元素放在单独的窗口中可以有所帮助。也许窗口本身隐藏了一些东西以便于绘制?

    我的一款软件具有很多图形元素和动画。但是我从来没有遇到过你的问题。如何创建一个测试项目并尝试类似的事情?有时,这有助于在更清晰的项目结构上发现问题。

    我创建了一个简单的演示,该演示在窗口中具有100 * 100个子层。似乎一点问题都没有。
    import Cocoa
    
    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate {
    
    @IBOutlet weak var window: NSWindow!
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
        self.window.contentView?.wantsLayer = true
    
        let size = 10
        for i in 0..<10000 {
            let x = i%100
            let y = i/100
    
            let layer = CALayer()
            layer.frame = NSRect(x: x*size, y: y*size, width: size, height: size)
            layer.backgroundColor = .random()
            self.window.contentView?.layer?.addSublayer(layer)
        }
    
    }
    
    
    
       func applicationWillTerminate(_ aNotification: Notification) {
            // Insert code here to tear down your application
        }
    }
    
    extension CGFloat {
        static func random() -> CGFloat {
            return CGFloat(arc4random()) / CGFloat(UInt32.max)
        }
    }
    
    extension CGColor {
        static func random() -> CGColor {
            return CGColor(red:   .random(),
                           green: .random(),
                           blue:  .random(),
                           alpha: 1.0)
        }
    }
    

    performance - 层托管的NSView,内部有很多CALayers(WindowServer-CPU 100%)-LMLPHP

    10-07 23:40