簡體   English   中英

展開協議類型的可選弱屬性時,迅速執行EXC_BAD_ACCESS

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM