【发布时间】:2018-08-01 09:12:26
【问题描述】:
当我尝试访问 Codable 子类实例的属性并且满足以下两个条件之一时,我的应用程序崩溃了:
- 子类是
Codable的多级子类 - 有一个函数调用
JSONEncoder().encode这个函数不必调用,它只需要在你实例化相关类的地方出现。
Entity.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:(初始视图控制器)
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的函数会导致崩溃。即使没有在任何地方调用该函数。如果你把
let _: Data? = try? JSONEncoder().encode(childEntity)放在ChildEntity的初始化之后,应用程序不会崩溃,即使你让我刚才讲的causesCorruptionEvenIfNotCalled函数。如果
ChildEntity直接继承自Codable,则没有问题,应用不会崩溃。
如何在保留 JSON 编码器的继承结构和功能的同时防止崩溃?
这是一个示例项目:https://drive.google.com/open?id=1mrhOmm4kOAdMjLk5nlFLDeo6vTsBo1Uv
【问题讨论】:
-
我无法在操场上重现这个,你确定没有其他事情发生吗?
-
普通项目也无法重现
-
您的描述不清楚
标签: swift inheritance exc-bad-access codable jsonencoder