未在异步块中捕获的无主属性

时间:2016-09-09 08:38:50

标签: swift swift3

我正在处理类似于此代码段的代码(这需要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)
} 

此代码崩溃,因为无主财产"客户"未在异步块中捕获。在异步块可以运行之前,客户对象将被释放。制作"客户"一个强大的参考工作,但它可能会导致参考周期导致泄漏。

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

1 个答案:

答案 0 :(得分:1)

您可以使用self.customer捕获强引用 a"捕获列表"在封闭中:

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

在封闭内,customerself.customer的强引用, 在关闭执行之前一直存在。这导致了 临时保留周期,但不是永久保留周期,因为 封闭最终会被执行。