2015-11-07 65 views
1

我想通過使用while循環每2秒拍攝一張照片。但是當我嘗試這個屏幕凍結。
這是取照片的功能:爲什麼iPhone在swift中使用while循環時似乎會凍結?

func didPressTakePhoto(){ 

    if let videoConnection = stillImageOutput?.connectionWithMediaType(AVMediaTypeVideo){ 
     videoConnection.videoOrientation = AVCaptureVideoOrientation.Portrait 
     stillImageOutput?.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: { 
      (sampleBuffer, error) in 

      if sampleBuffer != nil { 


       let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer) 
       let dataProvider = CGDataProviderCreateWithCFData(imageData) 
       let cgImageRef = CGImageCreateWithJPEGDataProvider(dataProvider, nil, true, .RenderingIntentDefault) 

       let image = UIImage(CGImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.Right) 

       UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) 

       //Adds every image taken to an array each time the while loop loops which will then be used to create a timelapse. 
       self.images.append(image) 


      } 


     }) 
    } 


} 

拍照時我有一個按鈕時調用計數變量等於0,這將使用此功能在while循環,但是當結束按鈕被按下時,這個變量等於1,所以while循環結束。
這是startPictureButton動作的樣子:

@IBAction func TakeScreanshotClick(sender: AnyObject) { 

    TipsView.hidden = true 
    XBtnTips.hidden = true 

    self.takePictureBtn.hidden = true 

    self.stopBtn.hidden = false 

    controls.hidden = true 
    ExitBtn.hidden = true 

    PressedLbl.text = "Started" 
    print("started") 

    while count == 0{ 

     didPressTakePhoto() 

     print(images) 
     pressed = pressed + 1 
     PressedLbl.text = "\(pressed)" 
     print(pressed) 

     sleep(2) 

    } 


} 

但是當我運行這一點,並開始延時屏幕看起來凍結。
有誰知道如何停止發生凍結 - 但也要將每個圖像添加到數組 - 以便我可以把它變成一個視頻?

回答

5

問題是在UI線程上運行處理單擊按鈕(TakeScreanshotClick方法)的方法。所以,如果這個方法永遠不會退出,那麼UI線程就會陷入其中,並且UI會凍結。

爲了避免它,你可以在後臺線程上運行你的循環(閱讀大約NSOperationNSOperationQueue)。有時你可能需要從後臺線程派發一些東西到UI線程(例如UI更新命令)。

更新:蘋果有一個非常好的文檔(迄今爲止我所見過的最好的)。看看這個:Apple Concurrency Programming Guide

+0

謝謝,我將如何在我的程序中實現這一點? –

+0

@AndrewHarris,不幸的是寫了很長時間(考慮到操作取消應該被照顧),而且我現在沒有太多時間。可能是別人會這樣做的。不過,如果您搜索有關異步界面的信息,則應該可以實現它。 – FreeNickname

+0

謝謝,我做了一些研究,發現這一點,但我不完全理解它,但它的工作部分, - dispatch_async(dispatch_get_main_queue()){}並讓優先級= DISPATCH_QUEUE_PRIORITY_DEFAULT; dispatch_async(dispatch_get_global_queue(priority,0)){//做一些任務dispatch_async(dispatch_get_main_queue()){//更新一些UI}}這似乎在做詭計 –

3

您正在主UI線程上調用sleep命令,從而凍結所有其他活動。

另外,我看不到你設置count = 1的位置? while循環不會永遠持續下去嗎?

+0

感謝,@IBAction FUNC StopClick(發件人:AnyObject){ takePictureBtn.hidden =假 stopBtn.hidden =真 controls.hidden =假 ExitBtn.hidden =假 計數= 1張 打印( 「停止」) 按壓= 0 PressedLbl.text = 「\(按壓)」 打印(圖像) } –

+0

對不起,忘記count = 1是在一個單獨的按鈕 –

相關問題