Unowned 属性 未在异步块中捕获

Unowned property not captured in async block

我正在使用结构类似于此代码段的代码(这需要 Swift 3):

import Dispatch

var processing = false

class Customer {
    var card: CreditCard!
    var name: String!

    init(name: String) {
        self.name = name
    }

    func createCard() -> CreditCard {
        card = CreditCard(customer: self)
        return card
    }

    func check() {
    }
}

class CreditCard {
    unowned let customer: Customer //if not "unowned" a reference cycle will result
    let queue = DispatchQueue.global() //needs Swift 3 to compile

    init(customer: Customer) {
        self.customer = customer
    }

    private func doBackgroundCheck() {
        self.customer.check()
    }

    func process() {
        queue.async {
            //self.customer is no captured
            self.doBackgroundCheck()
            print("processed")
            processing = false
        }
    }  
}

func issueCard(to name: String) {
    let c = Customer(name: name)
    let card = c.createCard()
    processing = true
    card.process()
}


//main
issueCard(to: "Tom")
while processing {
    sleep(1)
} 

这段代码崩溃了,因为无主的 属性 "customer" 没有在异步块中被捕获。客户对象在异步块 运行 之前被释放。使 "customer" 成为强引用是可行的,但它可能会导致引用循环,从而导致泄漏。

我无法在 Apple 文档中找到有关此类代码模式的任何指导。有人可以帮忙吗?谢谢!

您可以使用以下方法捕获对 self.customer 的强引用 闭包中的 "capture list":

func process() {
    queue.async { [customer = self.customer] in
        customer.check()
        print("processed")
        processing = false
    }
}

闭包内部,customer是对self.customer的强引用, 它存在直到闭包被执行。这导致 临时保留周期,但不是永久,因为 闭包最终被执行。