I have custom colors within my code. I use them several times and I would like to have them allocated only once.
The situation / problem
If we get a look at UIColor headers we can see the following :
[...]
// Some convenience methods to create colors. These colors will be as calibrated as possible.
// These colors are cached.
open class var black: UIColor { get } // 0.0 white
open class var darkGray: UIColor { get } // 0.333 white
[...]
I've created an extension
of UIColor, like so :
import UIKit
extension UIColor {
class func colorWithHexString(_ hex: String) -> UIColor {
print("(#function): (hex)")
// some code, then it return a UIColor
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
// Option A
open class var myColorOne : UIColor {
get {
return colorWithHexString("AABBCC")
}
}
// Option B
class func myColorTwo() -> UIColor {
return colorWithHexString("DDEEFF")
}
}
From there I can use my colors easily, with either having a variable or a function.
// A
UIColor.myColorOne
// B
UIColor.myColorTwo()
Sadly, I'm not fully happy with that. Indeed, every time I want to use those colors : a new UIColor allocation is made.
What I've tried
Apple managed to make their color cached apparently. I would like to do so myself too. I've tried several things but none seems to be ideal.
1 - Using dispatch_once ?
As visible on Swift page : the free function dispatch_once
is no longer available in Swift.
2 - Creating a constant (let) ?
I get the following error : extensions may not contain stored properties
3 - Creating a singleton ~
It does work (each color are created only once) with the following
import UIKit
class Colors : UIColor {
// Singleton
static let sharedInstance = Colors()
let myColorOne : UIColor = {
return UIColor.colorWithHexString("AABBCC")
}()
let myColorTwo : UIColor = {
return UIColor.colorWithHexString("DDEEFF")
}()
}
But it forces me to have one more file and call my colors like so
Colors.sharedInstance.myColorOne
Isn't there any way to get the colors I want like that UIColor.myColorOne
and have them cached like Apple does ?
See Question&Answers more detail:
os