当它们是结构时,引用语义如何在协议类型的集合中工作?

问题描述 投票:0回答:0

我在解码 JSON 对象时偶然发现内存泄漏,但我相信它与 JSONDecoder 具体无关。以下是演示该问题的示例:

struct AccountResponse: Codable {
    var accounts: [Account]?
}

struct Account: Codable {
    var id: String?
    var openedDate: Date?
}

protocol AccountProtocol {
    var id: String? { get }
    var openedDate: Date? { get }
}

extension Account: AccountProtocol {}

class ViewController: UIViewController {
    override func viewDidLoad() {
        test()
        super.viewDidLoad()
    }
    
    var userAccounts: [AccountProtocol]?
    
    func test() {
        let data =
        """
        {
          "accounts": [{
            "id": "2028658397",
            "openedDate": "2020-05-06T00:00:00Z"
          }]
        }
        """.data(using: .utf8)!
        
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        self.userAccounts = (try! decoder.decode(AccountResponse.self, from: data)).accounts
    }
}

当我使用 Instruments->Leaks 分析应用程序时,我总是遇到内存泄漏: memory leak

但问题是……如果我执行以下任何步骤,泄漏就会消失:

  • 在 userAccounts 数组中使用具体类型
    Account
    而不是协议
  • 使
    struct Account
    成为班级
  • AccountResponse
    中的账户声明更改为let而不是var
  • 修改
    Date
    类型的属性为
    String
    (这个对我来说特别奇怪)

这些与协议类型集合机制相关的“修复”背后的 ARC 逻辑是什么?

json protocols swift-protocols
© www.soinside.com 2019 - 2024. All rights reserved.