gpt4 book ai didi

swift - 在 Swift 中对继承自 Codable 的类进行子类化导致的崩溃

转载 作者:行者123 更新时间:2023-11-28 07:43:17 25 4
gpt4 key购买 nike

当我尝试访问 Codable 子类实例的属性并且满足以下两个条件之一时,我的应用程序崩溃了:

  1. 该子类是 Codable 的多级子类
  2. 有一个调用 JSONEncoder().encode 的函数不必调用该函数,它只需要出现在您实例化相关类的地方。

实体.swift:

class Entity: Codable {

}

ChildEntity.swift:

// If ChildEntity inherits from Entity, the app will crash
/* If ChildEntity simply implements Codable like so : class ChildEntity: Codable,
the app will not crash even with the 'causesCorruptionEvenIfNotCalled' function in ChildEntityController
*/
class ChildEntity: Entity {
var name: String = ""
}

ViewController.swift:(初始 View Controller )

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let childEntity: ChildEntity = ChildEntity()

// Simply having the function 'causesCorruptionEvenIfNotCalled' in the code (not calling it) causes 'childEntity' properties to become inacessible

// Before accessing the property, 'childEntity.name' is a normal empty String

let name: String = childEntity.name // CRASH: name cannot be accessed because of a EXC_BAD_ACCESS error

// At this point 'childEntity.name' is corrupted with random data but 'name' has an empty String
// You can get get the property's value but inspecting either 'name' and 'childEntity.name' throws and EXC_BAD_ACCESS error

print("name: \(name)")
}

// Commenting or removing this function's body will prevent all the issues below
func causesCorruptionEvenIfNotCalled(object: Entity) {
let _: Data? = try? JSONEncoder().encode(object)
}

}

有几件事我很困惑:

  • 只有调用 JSONEncoder().encode 的函数会导致崩溃。即使没有在任何地方调用该函数。

  • 如果你把 让 _: 数据? =试试? JSONEncoder().encode(childEntity)ChildEntity 初始化之后,应用程序不会崩溃,即使你让我刚才谈到的 causesCorruptionEvenIfNotCalled 函数以上。

  • 如果 ChildEntity 直接继承自 Codable,则没有问题,应用不会崩溃。

如何在保持 JSON 编码器的继承结构和功能的同时防止崩溃?

这是一个示例项目:https://drive.google.com/open?id=1mrhOmm4kOAdMjLk5nlFLDeo6vTsBo1Uv

最佳答案

似乎从 Codable 符合类继承在某种程度上不完全支持开箱即用。我不得不覆盖 func encode(to encoder: Encoder) throws 并在内部调用 super。我以为这是默认行为,但我错了。

ChildEntity 类现在如下所示:

class ChildEntity: Entity {
var name: String = ""

override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
}
}

从Swift核心代码来看,它并没有调用super: https://github.com/apple/swift/blob/master/stdlib/public/core/Codable.swift.gyb

这个错误似乎有点相关:https://bugs.swift.org/browse/SR-4772

关于swift - 在 Swift 中对继承自 Codable 的类进行子类化导致的崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51629481/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com