我正在尝试从视频中获取一系列图像。它运行良好,但我怀疑完成处理程序在哪个线程中调用。
我generateCGImagesAsynchronouslyForTimes:
在新操作中调用了此method(),并在完成处理程序中更新了UI。用户界面得到更新。
但是通常UI更新是否不会在辅助线程中发生?我的疑问是在当前调用线程或主线程中调用完成处理程序吗?
我的代码是:
__block unsigned int i = 0;
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
i++;
if(result == AVAssetImageGeneratorSucceeded){
//Create a block to save the image in disk
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSHomeDirectory()
stringByAppendingPathComponent:@"Documents"];
NSError *error = nil;
//Create file path for storing the image
NSString *videoOutputPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"VideoFrames%i.png", i]];
//Delete if already any image exist
if ([fileMgr fileExistsAtPath:videoOutputPath]){
if ([fileMgr removeItemAtPath:videoOutputPath error:&error] != YES)
NSLog(@"Unable to delete file: %@", [error localizedDescription]);
}
//Convert the CGImageRef to UIImage
UIImage *image = [UIImage imageWithCGImage:im];//**This line gives error: EXE_BAD_ACCESS**
//Save the image
if(![UIImagePNGRepresentation(image) writeToFile:videoOutputPath options:NSDataWritingFileProtectionNone error:&error])
NSLog(@"Failed to save image at path %@", videoOutputPath);
}];
//Add the operation to the queue
[self.imageWritingQueue addOperation:operation];
}
}
};
IIRC,是的。但是您可以对其进行测试,并且为了安全起见,可以将代码包装在将其分派到主线程的代码块中。
一般而言,回调必须返回主线程,因为如果不是主线程,则不能保证其启动的线程正在运行运行循环。
除非您正在调度要与其他操作(依赖项)相关联的创建块,否则我不确定该块为您提供了什么优势,因为图像加载是异步的,因此您可以从主线程触发它而不会阻塞任何东西。
根据您的评论,在这种情况下,您应该切换代码。在完成块内创建块操作,该块操作为您提供图像。将每个块操作添加到您的队列中。块操作仅获取图像并将其保存到磁盘。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句