2015-11-07 55 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是在一个单独的按钮 –

相关问题