Silver


#1
func takeOwnershipOfAsset(asset: Asset) {
    guard asset.owner == nil else {
      print("Asset \(asset.name) is already owned by \(asset.owner!.name)")
      return
    }
    asset.owner = self
    assets.append(asset)
    accountant.gainedNewAsset(asset)
}

#2

Another solution:

func takeOwnershipOfAsset(asset: Asset) {
        if asset.owner == nil {
            asset.owner = self
            assets.append(asset)
            accountant.gainedNewAsset(asset)
        } else {
            print("Error: \(name), this \(asset.name) already has an owner.")
        }
    }

#3

Rather than just check to see if it’s available for ownership, seems to me we should allow ownership to change:

[code] func takeOwnershipOfAsset(asset: Asset) {
if asset.owner?.name != self.name {
asset.owner?.giveUpOwnershipOfAsset(asset)
asset.owner = self
assets.append(asset)
accountant.gainedNewAsset(asset)
}
}

func giveUpOwnershipOfAsset(asset: Asset) {
    if asset.owner?.name == self.name {
        asset.owner = nil
        assets = assets.filter { $0.name != asset.name }
        accountant.removeAsset(asset)
    }
}

[/code]


#4

I did something similar to astericky, but I throw an error. Then I noticed that any asset that was the subject of an invalid attempt to take ownership (and thus threw an error) was not deallocated, even though set to nil. I had the remove the associated value in the enum (the code below is before removing the reference ) for it to work, so I assume the enum was holding a strong reference? I wonder if that is true, and if so how to make it a weak reference, or is it actually a memory leak one needs to worry about?

func takeOwnership(of asset: Asset) throws {
    accountant.gained(asset) {
        if asset.owner == nil {
            asset.owner = self
            assets.append(asset)
        } else {
            throw Person.Error.assetNotForSale(asset)
        }
    }
}

enum Error: Swift.Error {
    case assetNotForSale(Asset)
}