我试图在矩形请求上设置属性。 我试图设置最小尺寸,纵横比等,但出现以下错误。
致命错误:尝试读取无主引用,但对象已解除分配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
在这里,将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
通过onSelect
闭包中的变量捕获来引用vcA
。发生这种情况是因为为了使闭包在将来执行代码,它们必须保留对闭包中使用的所有对象的引用,在示例中,vcA
是唯一使用的对象,因此闭包包含对它的引用,vcB
保存对闭包的引用。要防止此保留周期,请执行以下操作:
viewControllerB.onSelect = { [unowned self]
self.onSelection()
}
或
viewControllerB.onSelect = { [weak self]
self?.onSelection()
}
将导致闭包无法捕获vcA
这意味着将没有保留周期。使用weak
比使用更安全unowned
.闭包不能保证未捕获的对象在执行时会存在,weak
允许nil
这些对象,unowned
在某种程度上规定它不会被nil
并指示程序崩溃。