我的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
它不起作用。有人可以解释一下吗?
答案 0 :(得分:1)
Swift目前不能很好地处理使用泛型的非类类型。
EXC_BAD_ACCESS
的实际位置是Weak(value)
的结果分配给var w
的时间。您可以通过在println
周围添加var w = Weak(value)
语句来查看此内容。
要解决Swift的这些问题,您需要使用非类类型的Box值将它们与泛型一起使用。
希望在接下来的几个版本的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