2017-03-09 68 views
2

我正在实现一个Mac应用程序起诉CGDisplayStream的屏幕捕捉,类似的问题问here,但是在斯威夫特。使用CGDisplayStream与队列

下面是我的应用程序的单一视图控制器的代码我有:

override func viewDidAppear() { 

    super.viewDidAppear() 

    let backgroundQueue = DispatchQueue(label: "com.app.queue", 
             qos: .background, 
             target: nil) 


    let displayStream = CGDisplayStream(dispatchQueueDisplay: 0, outputWidth: 100, outputHeight: 100,pixelFormat: Int32(k32BGRAPixelFormat), properties: nil, queue: backgroundQueue) { (status, code, iosurface, update) in 

     switch(status){ 
     case .frameBlank: 
      print("FrameBlank") 
      break; 
     case .frameIdle: 
      print("FrameIdle") 
      break; 
     case .frameComplete: 
      print("FrameComplete") 
      break; 
     case .stopped: 
      print("Stopped") 
      break; 
     } 

     self.update() 

    } 

    displayStream?.start() 

} 


func update(){ 
    print("WORKING") 
} 

什么似乎情况是,排队过程中没有被正确初始化,但我不知道......当应用程序启动,self.update()被调用一次,但只有一次。鉴于显示流已经正确启动,我期望这个函数被重复调用,但它只被调用一次。

任何人有任何想法?我没有正确设置队列吗?

谢谢!

回答

2

的问题是,以不displayStream参考被保持的外viewDidAppear ,所以流将在该方法的返回 被释放。

使其成为视图控制器的属性应解决的问题:

class ViewController: NSViewController { 

    var displayStream: CGDisplayStream? 

    override func viewDidAppear() { 
     super.viewDidAppear() 

     // ... 

     displayStream = CGDisplayStream(...) 
     displayStream?.start() 
    } 

    override func viewWillDisappear() { 
     super.viewWillDisappear() 
     displayStream?.stop() 
     displayStream = nil 
    } 

} 

viewWillDisappear断裂释放该流的保留周期 并且允许视图控制器被解除分配(如果它是 一部分视图控制器层次)。

+0

是啊,这正是问题。谢谢! – narner

+0

有类似症状的另一种疑难杂症这难倒我了片刻:在处理程序回调只在有更改输入显示火灾。因此,如果您像我一样在外部显示器上完成大部分工作,则只有在将鼠标移动到您选择的显示器上作为输入显示器时,回调才可能触发。 –