![](/img/trans.png)
[英]EXC_BAD_ACCESS when safely unwrapping optional on NSManagedObject
[英]Swift EXC_BAD_ACCESS when unwrapping optional weak property of protocol type
我的Xcode游樂場中有以下代碼,在最后一行給出了EXC_BAD_ACCESS
錯誤:
protocol SomeProtocol: class {
func test()
}
class SomeClass: SomeProtocol {
func test(){}
}
struct Weak<T: AnyObject> {
weak var value: T?
init(_ value: T) {
self.value = value
}
}
var value: SomeProtocol = SomeClass()
var w = Weak(value)
w.value?.test() // EXC_BAD_ACCESS
如果我將@objc
添加到協議定義中,則代碼將執行而沒有任何錯誤:
import Foundation
@objc protocol SomeProtocol: class {
func test()
}
class SomeClass: SomeProtocol {
@objc func test(){}
}
struct Weak<T: AnyObject> {
weak var value: T?
init(_ value: T) {
self.value = value
}
}
var value: SomeProtocol = SomeClass()
var w = Weak(value)
w.value?.test()
我懷疑這些Apple文檔行在某種程度上與我的情況有關:
即使您不與Objective-C互操作,如果您希望能夠檢查協議一致性,也需要使用@objc屬性標記協議。
但是我不明白為什么沒有@objc
不能正常工作。 有人可以解釋嗎?
Swift當前無法很好地使用具有泛型的非類類型。
EXC_BAD_ACCESS
的實際位置是將Weak(value)
的結果分配給var w
。 您可以通過在var w = Weak(value)
周圍添加println
語句來查看此情況。
為了解決Swift的這些問題,您需要將非類類型的值裝箱以將它們與泛型一起使用。
希望在接下來的幾個Swift Apple版本中,這些問題將得以解決,而我們不再需要將值裝箱。
final class Box<T> {
private var value: T
init(_ value: T) {
self.value = value
}
var unbox: T {
return value
}
}
protocol SomeProtocol : AnyObject {
func test()
}
class SomeClass: SomeProtocol {
func test(){
println("Test")
}
}
struct Weak<T: AnyObject> {
weak var value: T?
init(_ value: T) {
println("Weak Init Start")
self.value = value
println("Weak Init Stop")
}
}
var value: SomeProtocol = SomeClass()
//Method in Question
println("Before Weak Init")
// var w = Weak(value) // EXC_BAD_ACCESS
println("After Weak Init")
//w.value?.test()
// Method with Box
var box = Box(value)
var w = Weak(box)
w.value?.unbox.test() // prints "Test"
w = Weak(Box(value))
w.value?.unbox.test() // nil, since nothing retains the Box(value) result
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.