gpt4 book ai didi

objective-c - 使队列线程安全

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:17:22 25 4
gpt4 key购买 nike

我有一个相机 session ,我正在从缓冲区拍摄图像:

   -(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);

CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
//rotate image 90°
ciImage = [ciImage imageByApplyingTransform:CGAffineTransformMakeRotation(-M_PI/2.0)];
}

我在图像上应用过滤器,我希望它在另一个队列上应用过滤器,它不是线程安全的,所以如果我快速拍摄图像,它会将图像混合在一起(从左边开始 50/50对吧,我想),但我试图让它成为线程安全的,它不会通过使用 NSLock 来工作。或 NSRecursiveLock,因为它将图像混合在一起。

dispatch_async(filterQueue, ^{
CIImage *scaleImage = [CIFilter filterWithName:@"CILanczosScaleTransform" keysAndValues:kCIInputImageKey, ciImage, @"inputScale", [NSNumber numberWithFloat:0.5], nil].outputImage;

CGImageRef cgImage = [imageContext createCGImage:scaleImage fromRect:scaleImage.extent];
[self.pictureArray addObject:[UIImage imageWithCGImage:cgImage]];
CGImageRelease(cgImage);
});

有人可以帮助我吗?我对如何使代码成为线程安全的了解不多

图像像这样混合:http://i.stack.imgur.com/wjrIl.png

最佳答案

首先,上述代码中唯一不是线程安全的部分是对 addObject: 的调用。您可以通过将 addObject: 调用移至主线程,或使 pictureArray 访问更加线程安全,从而使您的代码线程安全。让我们看看两者。

转移电话

这几乎肯定是您想要的方式。

dispatch_async(filterQueue, ^{
CIImage *scaleImage = [CIFilter filterWithName:@"CILanczosScaleTransform" keysAndValues:kCIInputImageKey, ciImage, @"inputScale", [NSNumber numberWithFloat:0.5], nil].outputImage;

CGImageRef cgImage = [imageContext createCGImage:scaleImage fromRect:scaleImage.extent];
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
cgImage = NULL; // Always set to NULL after you release something
dispatch_async(dispatch_get_main_queue(), ^{
[self.pictureArray addObject:image];
});
});

请注意,我在后台线程上做了尽可能多的事情。我只是将最后的 addObject: 移动到主线程。

线程安全的addImage:

如果您经常从后台线程调用 addObject:,将它提升到它自己的方法中可能会很好,如下所示:

- (void)addImageOnMainThread:(UIImage *)image {
dispatch_async(dispatch_get_main_queue(), ^{
[self.pictureArray addObject:image];
});
}

线程安全的图片数组:

如果突变非常普遍并且锁定是一个性能问题,这会更好。使用屏障可以非常快速访问,但代价是代码更复杂。

- (UIImage *)imageAtIndex:(NSUInteger)index {
UIImage *result = nil;
dispatch_sync(self.pictureArrayQueue,
^{ result = self.pictureArray[index]; });
return result;
}

- (void)addImage:(UIImage *)image {
dispatch_barrier_async(self.pictureArrayQueue,
^{ [self.pictureArray addObject:image]; });
}

请注意,这里有一个新的调度队列用于访问 pictureArray。您可以构建更多的读取器和写入器(如 removeImageAtIndex: 等)。所有读取器都使用 dispatch_sync。所有编写器都使用 dispatch_barrier_async。这需要更多代码,除非通过这些方法,否则您绝不能直接访问 pictureArray。优点是如果突变非常普遍,它会快得多。

关于objective-c - 使队列线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13802403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com