Почему iPhone зависает при использовании цикла while с swift?
Я пытаюсь сделать снимок каждые 2 секунды, используя цикл 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)
}
})
}
}
Чтобы сделать снимок, у меня есть кнопка, которая будет использовать эту функцию в цикле while, когда переменная с именем count равна 0, но когда нажата кнопка завершения, эта переменная равна 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)
}
}
Но когда я запускаю это и запускаю timelapse, экран выглядит замороженным.
Кто-нибудь знает, как остановить замораживание - но также добавить каждое изображение, снятое в массив - чтобы я мог превратить это в видео?
2 ответа
Проблема в том, что метод, который обрабатывает нажатия на кнопку (TakeScreanshotClick
метод) запускается в потоке пользовательского интерфейса. Таким образом, если этот метод никогда не завершается, поток пользовательского интерфейса застревает в нем, и пользовательский интерфейс зависает.
Чтобы избежать этого, вы можете запустить свой цикл в фоновом потоке (читайте NSOperation
а также NSOperationQueue
). Иногда вам может понадобиться отправить что-то из фонового потока в поток пользовательского интерфейса (например, команды для обновления пользовательского интерфейса).
ОБНОВЛЕНИЕ: Apple имеет действительно отличную документацию (лучшее из того, что я видел до сих пор). Взгляните на это: Руководство по программированию параллелизма Apple.
Вы вызываете команду sleep в основном потоке пользовательского интерфейса, тем самым замораживая все остальные действия.
Кроме того, я не вижу, где вы установите количество = 1? Не будет ли цикл while продолжаться вечно?