【问题标题】:How to create several cached UIColor如何创建几个缓存的 UIColor
【发布时间】:2017-06-26 17:02:53
【问题描述】:

我的代码中有自定义颜色。我多次使用它们,我希望它们只分配一次。

情况/问题

如果我们查看 UIColor 标题,我们可以看到以下内容:

[...]

// 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

[...]

我创建了一个 UIColor 的 extension,如下所示:

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")
    }
}

从那里我可以轻松地使用我的颜色,无论是变量还是函数。

// A
UIColor.myColorOne

// B
UIColor.myColorTwo()

很遗憾,我对此并不完全满意。确实,每次我想使用这些颜色时:都会进行新的 UIColor 分配。

我尝试过的

Apple 显然设法使他们的颜色缓存起来。我自己也想这样做。我已经尝试了几件事,但似乎没有一个是理想的。

1 - 使用 dispatch_once ✗

在 Swift 页面上可见:免费功能 dispatch_once 在 Swift 中不再可用。

2 - 创建一个常量 (let) ✗

我收到以下错误:扩展可能不包含存储的属性

3 - 创建一个单例 ~

它确实有效(每种颜色只创建一次)

import UIKit

class Colors : UIColor {
    
    // Singleton
    static let sharedInstance = Colors()
    
    let myColorOne : UIColor = {
        return UIColor.colorWithHexString("AABBCC")
    }()
    
    let myColorTwo : UIColor = {
        return UIColor.colorWithHexString("DDEEFF")
    }()
    
}

但它迫使我再拥有一个文件并像这样称呼我的颜色

Colors.sharedInstance.myColorOne

有没有办法像UIColor.myColorOne 那样获得我想要的颜色并像 Apple 那样缓存它们?

【问题讨论】:

  • @Grimxn,全局变量(甚至懒惰初始化)不是 不好的做法/想法 吗?此外,它不会像其他颜色UIColor.white 那样被调用。 Apple 是如何编写他们的...可能需要在第一次初始化后存储颜色并在以后的调用中获取它(不确定这里的性能,与单例相比)。
  • ... ...对不起!

标签: swift uicolor swift-extensions


【解决方案1】:

您可以使用与 Using a dispatch_once singleton model in Swift,即静态 常量存储属性 它们被延迟初始化(并且只有一次)。这些可以定义 直接在UIColor 扩展中:

extension UIColor {
    convenience init(hex: String) {
        // ...          
    }

    static let myColorOne = UIColor(hex:"AABBCC")
    static let myColorTwo = UIColor(hex:"DDEEFF")
}

【讨论】:

    【解决方案2】:

    可能有更好的方法,但使用全局变量(如评论中提到的 Grimxn)是解决问题的一种方法。

    以下是您可以复制并粘贴到 Playground 的示例:

    import UIKit
    
    extension UIColor {
    
        class func colorWithHexString(_ hex: String) -> UIColor {
            print("allocate color")
            // do you conversion here...
            return UIColor.black
        }
    
    }
    
    private let myPrivateColorOne = UIColor.colorWithHexString("#ffffff")
    
    extension UIColor {
    
        open class var myColorOne: UIColor {
            get {
                print("get color")
                return myPrivateColorOne
            }
        }
    
    }
    
    UIColor.myColorOne
    UIColor.myColorOne
    

    执行代码时,getter 会被调用两次,但colorWithHexString 只调用一次。

    【讨论】:

      【解决方案3】:

      您可以使用您的单例来存储生成的 UIColor 值,并通过扩展 UIColor 并将访问权放在那里来解决 Colors.sharedInstance.myColorOne 命名问题:

      extension UIColor {
          class func myColorTwo() -> UIColor {
              return Colors.sharedInstance.myColorTwo
          }
      }
      

      【讨论】:

        【解决方案4】:

        在 Swift 3 中:

        extension UIColor {
            class func color(hexString: String) -> UIColor {
                // ...
            }
        
            static let myColorOne = color(hexString: "AABBCC")
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-09-08
          • 1970-01-01
          • 2014-07-09
          • 1970-01-01
          • 1970-01-01
          • 2011-08-26
          • 1970-01-01
          • 2015-02-20
          相关资源
          最近更新 更多