我正在尝试在矩形请求上设置属性。 我试图设置最小尺寸,宽高比和其他尺寸,但出现以下错误。
致命错误:尝试读取一个未拥有的引用但对象已被释放2018-08-13 16:08:09.081049 + 0100 app [4000:1277980]致命错误:尝试读取一个未拥有的引用但对象已被释放
func performVisionRequest(image: CGImage, orientation: CGImagePropertyOrientation) {
DispatchQueue.global(qos: .userInitiated).async {
do {
let imageRequestHandler = VNImageRequestHandler(cgImage: image, orientation: orientation, options: [:])
try imageRequestHandler.perform(
[VNDetectRectanglesRequest(completionHandler:{ req, err in
self.rectanglesRequest(request:req, error:err)
})]
)
} catch let error as NSError {
self.sliceCompletion([UIImage]())
print("Failed to perform vision request: \(error)")
}
}
}
func rectanglesRequest(request: VNRequest, error: Error?) {
if let err = error as NSError? {
noRect = true
var slices = [imageNo]
self.sliceCompletion(slices as! [UIImage])
slices = []
print("Failed during detection: \(err.localizedDescription)")
return
}
unowned let rectanglesRequestSet = VNDetectRectanglesRequest()
rectanglesRequestSet.minimumSize = 0.07
rectanglesRequestSet.minimumAspectRatio = 0.2
rectanglesRequestSet.maximumAspectRatio = 0.3
rectanglesRequestSet.quadratureTolerance = 22.0
答案 0 :(得分:2)
此处将rectanglesRequestSet
标记为unowned
并不好,因为它会导致它在使用前以及尝试向已释放的unowned
对象发送消息时被释放。将会崩溃,这说明了您收到的消息:
试图读取一个未拥有的引用,但该对象已经被释放
unowned
用于打破保留周期,这种保留周期是在类的属性通常通过闭包将引用保留给类本身时发生的。例如:
class ViewControllerA: UIViewController {
let viewControllerB = UIViewControllerB()
override func viewDidLoad() {
super.viewDidLoad()
viewControllerB.onSelect = {
self.onSelection()
}
}
func onSelection() {
// do something
}
}
class ViewControllerB: UIViewController {
var onSelect: (() -> Void)?
}
例如,上面的代码创建了一个vcA
-> vcB
-> onSelect
-> vcA
的保留周期,其中vcA
是ViewControllerA
和vcB
是ViewControllerB
的实例。 vcA
和vcB
永远不会被释放,因为vcA
拥有对vcB
的引用,因为它是一个属性。并且,vcB
通过vcA
闭包中的变量捕获来持有对onSelect
的引用。发生这种情况的原因是,为了使闭包将来能够执行代码,它们必须持有对闭包中使用的所有对象的引用,在示例vcA
是唯一使用的对象,因此闭包保留对其的引用,并且vcB
引用了闭包。为防止此保留周期:
viewControllerB.onSelect = { [unowned self]
self.onSelection()
}
或
viewControllerB.onSelect = { [weak self]
self?.onSelection()
}
将导致闭包不捕获vcA
,这意味着将没有保留周期。使用weak
比使用unowned
更安全。闭包不能保证未捕获的对象将在执行时出现weak
,将允许这样的对象成为nil
,unowned
在某种程度上规定它将不会nil
,并指示程序崩溃。