APvG APvG - 1 month ago 21
Swift Question

Swift 3 lazy caching with enums

I am making a game in Swift 3, and I was wondering what would be best practice to lazy cache an SKTexture inside an enum (or struct). What I want is to create an SKTexture only once, and only when it is required. I could create a Singleton, with a (Dictionary / Set / Cache / ...) var and only append a new SKTexture to this var, if a key doesn't already exists or return the value if it does exists, but I have the feeling this should be possible with an enum as well.

Answer

For the case of a struct, you could simply use a lazy property of your SKTexture:

struct Foo {
    lazy var myTexture: SKTexture = { 
        /* some logic to construct texture only
           ever (at most) once _per Foo instance_ */ 
        return someInitializedSKTextureInstance 
    }()
    /* or, as an immutable
    lazy var myTexture: SKTexture = ... */       
}

For an instance of Foo, theFooInstance.myTexture will be instantiated at most once, but the once-only executed closure above.

Enumerations, however, cannot use stored properties, which means you cannot use the approach above. You could, however, use a static property in an enum: these are lazy by default, and will be instantiated only (at most) once at the first call to them. The difference here is naturally (due to static) that this once-only insantiation will hold globally for the enum _type), and not for instances of the enum.

enum Foo {
    case bar, baz
    static var texture: SKTexture = { 
        /* logic to construct some texture ... */
        return someInitializedSKTextureInstance 
    }()
}

Naturally the static approach could be used also for the struct case.