alibaba / alibaba/HandyJSON

在 xcode 工程的 Build setting 设置特定的优化模式, 无法正确转换常量 Int 型

Open
#262 2 comments 2 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
4.3k
Forks
677
PR merge metrics
No merged PRs in 30d

Description

Bug 复现方法:

1. 在 Build setting 中设置:
```
Enable_testability: No,
Swift_compilation_mode: whole module,
Swift_optimization_level: optimize for speed 或 optimize for size
```

2. 用 HandyJSON 把 JSON 转成 Model 过程当中,Model 可能是 Struct, Class, NSObject 其中的任何一种

3. 并且 Model 中有常量( let )属性时, 常量属性不能从 JSON 获得具体的值

原因推测:
假设有 Model 如下
```
struct A {
let a1: Int = 0
}
let a: A = A()
```
在特殊的优化模式下(那三个 xcode build setting 具体做了什么还不了解, 望指出), 一个实例对象 a, 如果包含常量变量 a1, 常量变量 a1 的实际存贮位置不在 a 的地址处, 很可能被编译器优化到了静态变量区.

所以当用 HandJSON 通过 a 的地址查到 a1 的地址, 假设赋值为 1
当进行获取 a.a1 的时候, 取的值是静态变量区(?)的值 0, 而不是当时赋的值 1

如果用 HandyJSON 的方法找到 a.a1 的地址, 会发现, 值已经被写到 &(a.a1) 处了, 但读取时, 显然不是在此处读的

疑惑:
如果编译器把一个实例的常量变量, 优化到某个地方, 那该实例应该会存一个指向常量变量的指针, 这个指针存在了哪里? 肯定不在实例变量的地址处(打印 a 的内存布局, 没有发现指针), 难道有一个映射表?
编译器做此次优化的目的是什么, 在 a 的地址处, 还是预留了 a1 变量的存储空间, 并没有对空间进行优化, 甚至很可能多了一个映射表, 难道有可能是读取速度快?

Contributor guide

No contributing guide indexed for this repository

Research direction

Begin by reproducing HandyJSON model conversion with let Int properties under the three listed Xcode build settings, using struct, class, and NSObject models. No source file or test is named; done means identifying the cause and correcting or clearly constraining deserialization so the JSON value is read correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.