ios - 展开协议(protocol)类型的可选弱属性时的 Swift EXC_BAD_ACCESS

标签 ios objective-c swift exc-bad-access

我的 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/

相关文章:

objective-c - 如何关联多个 NSMenuItems 的状态,使它们互斥?

发送到实例的 iOS 类别属性无法识别的选择器

objective-c - wait_fences : failed to receive reply: 10004003 error still appearing

ios - 库胖文件不起作用

ios - IOS (iPad 2) 上 AIR 3.9 中的 StageWebView

ios - 当仍然绘制旧对象时,内存中的对象被破坏并重新绘制

ios - 如何分离在文本字段上输入的表情符号(通过默认键盘)

ios - 如何快速将枚举存储到可变数组中

ios - swift : Animate width and height of UIButton

ios - ios webview使用的浏览器