在Swift中缓存静态函数结果?

时间:2015-07-23 19:46:51

标签: ios swift caching ios8

我有一个静态函数,它生成一个UIColor对象,因此可以在整个应用程序中多次重复使用它。我不希望每次都运行此代码,但实际上只是第一次将其放入缓存中,然后让任何后续检索从缓存中获取它。唯一需要注意的是这个值可能会发生变化,因此我不想永久保留此值,而只是将其保留在内存中,因此如果应用程序重新启动,它将获取最新值并在整个生命周期内使用它。

以下是我的功能:

class AppConfig: NSObject {   
    static func getGlobalTintColor(alpha: Float = 1) -> UIColor! {
        let colors = split(someVarFromInfoPlist) { $0 == "," }
        let red = CGFloat(colors[0].toInt() ?? 0) / CGFloat(255)
        let green = CGFloat(colors[1].toInt() ?? 0) / CGFloat(255)
        let blue = CGFloat(colors[2].toInt() ?? 0) / CGFloat(255)
        return UIColor(red: red, green: green, blue: blue, alpha: CGFloat(alpha))
    }
}

我不希望getGlobalTintColor每次都运行该逻辑。那么如何在第一次缓存它并让它在应用程序的生命周期的其余部分中提供?

5 个答案:

答案 0 :(得分:3)

您正在描述static 变量而不是功能。为变量赋予一个创建颜色的初始化函数。

class AppConfig: NSObject {
    static var alpha : CGFloat = 1
    static var globalTintColor : UIColor = {
        // figure out color once, possibly based on `alpha`
        return theColor
    }()
}

这是有效的,因为静态var初始值设定项是 lazy ;它可能取决于您的alpha,并且在您第一次真正询问其值之前,它不会被初始化。此外,此后初始化程序函数将不再运行(除非您退出并重新启动应用程序),这正是您正在寻找的。

答案 1 :(得分:1)

可能是这样的:

class AppConfig: NSObject {   
    private static var tintColor: UIColor?

    static func getGlobalTintColor(alpha: Float = 1) -> UIColor! {
        if tintColor == nil {
            let colors = split(someVarFromInfoPlist) { $0 == "," }
            let red = CGFloat(colors[0].toInt() ?? 0) / CGFloat(255)
            let green = CGFloat(colors[1].toInt() ?? 0) / CGFloat(255)
            let blue = CGFloat(colors[2].toInt() ?? 0) / CGFloat(255)
            tintColor = UIColor(red: red, green: green, blue: blue, alpha: CGFloat(alpha))
        }
        return tintColor!.colorWithAlphaComponent(CGFloat(alpha))
    }
}

答案 2 :(得分:1)

您可以创建一个返回函数的函数,将其返回值缓存到属性中,然后调用存储在该属性中的函数来计算取决于alpha的实际颜色。

这是“缓存”功能:

private static func _getGlobalTintColor() -> (Float) -> UIColor {
    let colors = split(someVarFromInfoPlist) { $0 == "," }
    let red = CGFloat(colors[0].toInt() ?? 0) / CGFloat(255)
    let green = CGFloat(colors[1].toInt() ?? 0) / CGFloat(255)
    let blue = CGFloat(colors[2].toInt() ?? 0) / CGFloat(255)
    return { alpha in UIColor(red: red, green: green, blue: blue, alpha: CGFloat(alpha)) }
}

如您所见,它返回一个带有签名(Float) -> UIColor的函数,即将alpha作为参数并返回颜色。

接下来,使用此函数的返回值初始化静态属性:

private static let globalColor = AppConfig._getGlobalTintColor()

最后,公开的静态函数接受一个alpha参数,并调用存储在该属性中的函数来获取并返回颜色:

static func getGlobalTintColor(alpha: Float = 1) -> UIColor {
    return self.globalColor(alpha)
}

请注意,可以删除第一个私有函数,并使用内联闭包初始化该属性:

class AppConfig: NSObject {
    private static let globalColor: Float -> UIColor = {
        let colors = split(someVarFromInfoPlist) { $0 == "," }
        let red = CGFloat(colors[0].toInt() ?? 0) / CGFloat(255)
        let green = CGFloat(colors[1].toInt() ?? 0) / CGFloat(255)
        let blue = CGFloat(colors[2].toInt() ?? 0) / CGFloat(255)
        return { alpha in UIColor(red: red, green: green, blue: blue, alpha: CGFloat(alpha)) }
    }()

    static func getGlobalTintColor(alpha: Float = 1) -> UIColor {
        return self.globalColor(alpha)
    }
}

答案 3 :(得分:1)

我建议使用固定的alpha和单独的函数分割成一个惰性static常量来指定alpha:

class AppConfig: NSObject {    
    static let globalTintColor: UIColor = {
        let colors = split(someVarFromInfoPlist) { $0 == "," }
        let red = CGFloat(colors[0].toInt() ?? 0) / CGFloat(255)
        let green = CGFloat(colors[1].toInt() ?? 0) / CGFloat(255)
        let blue = CGFloat(colors[2].toInt() ?? 0) / CGFloat(255)
        return UIColor(red: red, green: green, blue: blue, alpha: 1)
    }()

    static func globalTintColor(alpha: CGFloat) -> UIColor {
        return globalTintColor.colorWithAlphaComponent(alpha)
    }
}

答案 4 :(得分:0)

假设alpha输入在整个应用程序中可能不同,您可以考虑使用NSCache,其中键是由颜色和alpha形成的字符串,值是包含在持有者NSObject子类中的UIColor。

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSCache_Class/

NSCache将声明为:

private static let cache = NSCache()