我的 Xcode Playground 中有这段代码,它在最后一行给出了 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
添加到协议(protocol)定义中,则代码执行时不会出现任何错误:
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 文档中的这些行在某种程度上与我的案例有关:
Even if you are not interoperating with Objective-C, you need to mark your protocols with the @objc attribute if you want to be able to check for protocol conformance.
但我不明白为什么没有 @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
关于ios - 展开协议(protocol)类型的可选弱属性时的 Swift EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30292318/