swift - semantico - ejemplos de semantica yahoo
¿Cómo puedo crear un contenedor con semántica de copiado-escritura?(Rápido) (3)
Aquí hay un ejemplo un poco más simple.
struct COWExample1<T> {
private var box = Box<[T]>(value: [T]())
var count: Int {
return box.value.count
}
mutating func append(e: T) {
ensureBoxUniqueRefed()
box.value.append(e)
}
private mutating func ensureBoxUniqueRefed() {
if isUniquelyReferencedNonObjC(&box) == false {
box = box.duplicated()
}
}
}
private final class Box<T> {
var value: T
init(value: T) {
self.value = value
}
func duplicated() -> Box<T> {
return Box(value: value)
}
}
Tengo una estructura muy grande, y quiero asegurarme de que no se copie innecesariamente. ¿Cómo puedo hacer un contenedor de copiado por escrito?
Las respuestas anteriores no son incorrectas, pero hay una manera mucho más simple. El equipo de Swift tiene una lista de consejos de rendimiento y dicen:
La forma más fácil de implementar copy-on-write es componer estructuras de datos de copia con escritura, como Array.
¡No es mucho más simple que eso!
Un copy-on-write suele ser un contenedor struct
sobre algún objeto de respaldo.
public final class MutableHeapStore<T>: NonObjectiveCBase
{
public typealias Storage = T
public private(set) var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
}
public struct COW<T>
{
public typealias Storage = MutableHeapStore<T>
public typealias Value = T
public var storage: Storage
public init(storage: Storage)
{
self.storage = storage
}
public var value: Value
{
get
{
return storage.storage
}
set
{
if isUniquelyReferenced(&storage)
{
storage.storage = newValue
}
else
{
storage = Storage(storage: newValue)
}
}
}
public init(_ value: Value)
{
self.init(storage: Storage(storage: value))
}
}
extension COW: CustomStringConvertible
{
public var description: String
{
return String(value)
}
}
El truco consiste en afirmar que se isUniquelyReferenced
cada vez que se isUniquelyReferenced
el valor del isUniquelyReferenced
. Si el objeto de almacenamiento subyacente se referencia individualmente, no se debe hacer nada. Sin embargo, si existe otra referencia, se debe crear un nuevo almacenamiento.
¿Este código es seguro para subprocesos? Es exactamente tan seguro como cualquier otro tipo de valor, por ejemplo, Int
o Bool
.