我想异步构造一个对象func clickPicture() -> UIImage? {
if let videoConnection = stillImageOutput?.connection(withMediaType: AVMediaTypeVideo) {
videoConnection.videoOrientation = .portrait
stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) -> Void in
if sampleBuffer != nil {
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
let dataProvider = CGDataProvider(data: imageData!)
let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: .defaultIntent)
let image = UIImage(cgImage: cgImageRef!, scale: 1, orientation: .right)
return image //Unexpected non-void return value in void function
}
return nil //Unexpected non-void return value in void
})
}
return nil
}
,然后(从另一个线程)重复调用该对象的函数Delay
。
foo
但是,显然,第二次调用x.get()时会抛出异常。
处理这种情况的推荐方法是什么?使用如下所示的标志似乎是一个黑客。还有更好的方法吗?
struct Delay {
Delay(int d) {
sleep(d);
}
void foo() { }
};
struct Test {
Test() {
x = async(std::launch::async,
[&]() {return std::make_unique<Delay>(4);});
}
void run() { x.get()->foo(); }
std::future<std::unique_ptr<Delay>> x;
};
int main() {
auto t = Test();
// do other stuff...
t.run();
t.run(); // throwing an instance of 'std::future_error', "No associated state"
return 0;
}
答案 0 :(得分:1)
std::shared_future
是处理这种情况的推荐方法。
它可以通过从未来移动来构建,并支持其州的多个读者。这是一个独特的对象,因为一次交付的未来有一定的性能改进,并且因为如果你需要的话,创造一个共同的未来是如此微不足道。
只需将x
的类型更改为shared_future<std::unique_ptr<Delay>>
,即可完成。
但请注意,在上述情况下,unique_ptr
图层几乎没有意义。可能在你真正的问题中它不是。