共享引用和循环引用
Swift 引用跟踪由 Config.trackRef 控制。
启用引用跟踪
let fory = Fory(ref: true)
启用后,可跟踪引用的类型会保留对象标识和循环关系。
共享引用示例
import Fory
@ForyStruct
final class Animal {
var name: String = ""
required init() {}
init(name: String) {
self.name = name
}
}
@ForyStruct
final class AnimalPair {
var first: Animal? = nil
var second: Animal? = nil
required init() {}
init(first: Animal? = nil, second: Animal? = nil) {
self.first = first
self.second = second
}
}
let fory = Fory(ref: true)
try fory.register(Animal.self, id: 200)
try fory.register(AnimalPair.self, id: 201)
let shared = Animal(name: "cat")
let input = AnimalPair(first: shared, second: shared)
let data = try fory.serialize(input)
let decoded: AnimalPair = try fory.deserialize(data)
assert(decoded.first === decoded.second)
循环引用示例(使用 weak)
trackRef 会保留引用图,但不会改变 ARC 所有权。为避免内存泄漏,请在循环中至少一条边上
使用 weak。
import Fory
@ForyStruct
final class Node {
var value: Int32 = 0
weak var next: Node? = nil
required init() {}
init(value: Int32, next: Node? = nil) {
self.value = value
self.next = next
}
}
let fory = Fory(ref: true)
try fory.register(Node.self, id: 300)
let node = Node(value: 7)
node.next = node
let data = try fory.serialize(node)
let decoded: Node = try fory.deserialize(data)
assert(decoded.next === decoded)
注意事项
- 值类型(
struct、基本类型值)不具有对象标识语义 trackRef控制序列化图的对象标识,而不是 ARC 内存所有权- 对纯值载荷使用
trackRef=false以降低开销