"试图保留解除分配的对象"在循环参考

时间:2016-10-04 01:47:05

标签: ios swift xcode

我有一个追踪贵金属价格的计划。

TransactionDTO具有对AssetDTO的无主引用

AssetDTO代码段:

public class AssetDTO: Equatable {
var name: String!
var transactions = [TransactionDTO]()

TransactionDTO代码段:

unowned var asset: AssetDTO

init(asset:AssetDTO, type:Constants.TransactionType) {
    self.asset = asset
    self.type = type
    self.date = Date()
}

在UI控制器类中,我迭代表中的事务,并显示相关的金属(金,银等)。在我的viewDidLoad中,为了演示错误,我有以下代码

    var txs = [TransactionDTO]()
    for asset in assetManager.findAllMetals() {
        for tx in asset.transactions {
            txs.append(tx)
            print("the asset name for this is \(tx.asset.name)")
        }
    }

    for tx in txs {
        print("the asset name for this is \(tx.asset.name)")
    }

在第一个循环中,资产的名称打印,在第二个循环中,我得到:

libswiftCore.dylib`_swift_abortRetainUnowned:
0x108d44cc0 <+0>:  leaq   0x3058b(%rip), %rax       ; "attempted to retain deallocated object"
0x108d44cc7 <+7>:  movq   %rax, 0x95f0a(%rip)       ; gCRAnnotations + 8
0x108d44cce <+14>: int3   ->  0x108d44ccf <+15>: nop    

任何想法??

1 个答案:

答案 0 :(得分:1)

中删除unowned
    unowned var asset: AssetDTO

unowned实际上与weak类似,并且可能没有其他内容引用资产,因此它会被取消分配。但是,与weak不同,unowned并不会为您排除变量。因此,你得到的错误。如果将其更改为weak,您可能会发现它变为零。

由于您希望避免资产持有交易之间的循环引用,以及每个具有资产引用的交易,后者应该被声明为weak

问题在于assetManager.findAllMetals()的范围。如果没有任何东西可以引用它返回的资产,它们将被销毁。由于您具有对事务数组的引用,因此它们引用的资产将在第一次循环后被销毁。

最简单的解决方法是将您自己的引用保留在第一个循环的范围之外。沿着:

let allMetails = assetManager.findAllMetals()
var txs = [TransactionDTO]()
for asset in allMetals {
    for tx in asset.transactions {
        txs.append(tx)
        print("the asset name for this is \(tx.asset.name)")
    }
}

for tx in txs {
    print("the asset name for this is \(tx.asset.name)")
}