Swift 中不使用 ARC/引用计数的对象。
这是一个实验性的想法,旨在提供 Swift 中不包含引用计数和其他内置于原生 Swift 类中的特性的对象,从而减少性能开销。
核心概念是使用 Swift 宏来美化 UnsafeMutablePointer
和 UnsafeMutableRawPointer
的用法,以创建一个简单的对象系统。
dependencies: [
.package(
url: "https://github.com/joehinkle11/SwiftNRC",
.upToNextMajor(from: "1.0.0")),
],
targets: [
.target(
name: "YourTarget",
plugins: ["SwiftNRC"]
),
]
@NRC(
members: [
"var y": Int.self,
"private var x": Double.self,
"internal var z": Bool.self,
]
)
struct Example: SwiftNRCObject {
init() {
self = Self.allocate((
y: 5,
x: 4.3,
z: true
))
}
func flipZ() {
self.z.toggle()
}
func delete() {
self.deallocate()
}
}
let example = Example()
// XCTAssertEqual(example.x, 4.3) // no access, x is private
XCTAssertEqual(example.y, 5)
XCTAssertEqual(example.z, true)
example.z = false
XCTAssertEqual(example.z, false)
func scoped(_ copiedRef: Example) {
copiedRef.y = 100
}
XCTAssertEqual(example.y, 5)
scoped(example)
XCTAssertEqual(example.y, 100)
现在您还可以像在 C 结构体中一样,在对象的其他属性之间分配一个静态数组
@NRC(
members: [
"let before" : String.self,
"var myArray": NRCStaticArray(Int.self, 10),
"let after" : String.self,
]
)
struct ExampleStaticArray: SwiftNRCObject {
init?(_ numbers: Int...) {
guard numbers.count == Self.myArrayCount else {
return nil
}
self = .allocate()
self.initialize_before(to: "before string")
for (i, number) in numbers.enumerated() {
self.myArray.initialize(index: i, to: number)
}
self.initialize_after(to: "after string")
}
func delete() {
self.deallocate()
}
}
func arrayUsage() {
let exampleStaticArray = ExampleStaticArray(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)!
for i in 0..<10 {
XCTAssertEqual(exampleStaticArray.myArray[i], 9 - i)
exampleStaticArray.myArray[i] = i
}
let pointerToFirstElement = exampleStaticArray.myArrayPointer
}
所有静态数组的值(以及属性)在内存中都是连续的。这意味着您可以将指向数组第一个元素的指针传递给 C 函数,并且它可以读取数组中的所有值。
使用这些非引用计数的对象比 Swift 中的传统类性能更高。在性能至关重要的应用程序中,这种对象可以帮助减少与 ARC 相关的开销。