gpt4 book ai didi

ios - 从 Swift 字典中检索 CGColor 时遇到问题

转载 作者:行者123 更新时间:2023-11-28 09:42:24 24 4
gpt4 key购买 nike

我需要一个可以存储任何类型对象的 Swift 字典。一些值将是 CGColor 引用。我没有问题创建字典和存储 CGColor 引用。问题是如何安全地将它们取回。

let color = CGColor(gray: 0.5, alpha: 1)
var things = [String:Any]()
things["color"] = color
things["date"] = Date()
print(things)

这行得通,我得到了合理的输出。稍后我希望获得颜色(字典中可能存在也可能不存在。所以我很自然地尝试以下操作:

if let color = things["color"] as? CGColor {
print(color)
}

但这会导致错误:

error: conditional downcast to CoreFoundation type 'CGColor' will always succeed

最后我想出了:

if let val = things["color"] {
if val is CGColor {
let color = val as! CGColor
print(color)
}
}

这在 Playground 上没有任何警告,但在我的实际 Xcode 项目中,我在 if val is CGColor 行收到警告:

'is' test always true because 'CGColor' is a Core Foundation type

这个问题有好的解决办法吗?

我正在处理核心图形和图层,代码需要同时适用于 iOS 和 macOS,所以我尽量避免使用 UIColorNSColor

我确实找到了 Casting from AnyObject to CGColor? without errors or warnings这是相关的,但似乎不再相关,因为我不需要括号来消除警告,而且我正在尝试使用该问题未涵盖的可选绑定(bind)。

最佳答案

问题在于 Core Foundation 对象是不透明的,因此 CGColor 类型的值只不过是一个不透明的指针——Swift 本身目前对底层对象一无所知。因此,这意味着您当前不能使用 isas? 来有条件地使用它进行转换,Swift 必须始终允许给定的转换成功(这有望在未来改变不过——理想情况下,Swift 运行时会使用 CFGetTypeID 来检查不透明指针的类型。

一个解决方案,as shown by Martinthis Q&A , 就是使用 CFGetTypeID为了检查 Core Foundation 对象的类型——为了方便,我建议将其分解为一个函数:

func maybeCast<T>(_ value: T, to cfType: CGColor.Type) -> CGColor? {
guard CFGetTypeID(value as CFTypeRef) == cfType.typeID else {
return nil
}
return (value as! CGColor)
}

// ...

if let color = maybeCast(things["color"], to: CGColor.self) {
print(color)
} else {
print("nil, or not a color")
}

您甚至可以使用协议(protocol)将其推广到其他 Core Foundation 类型:

protocol CFTypeProtocol {
static var typeID: CFTypeID { get }
}

func maybeCast<T, U : CFTypeProtocol>(_ value: T, to cfType: U.Type) -> U? {
guard CFGetTypeID(value as CFTypeRef) == cfType.typeID else {
return nil
}
return (value as! U)
}

extension CGColor : CFTypeProtocol {}
extension CGPath : CFTypeProtocol {}

// Some CF types don't have their ID imported as the 'typeID' static member,
// you have to implement it yourself by forwarding to their global function.
extension CFDictionary : CFTypeProtocol {
static var typeID: CFTypeID { return CFDictionaryGetTypeID() }
}


// ...

let x: Any? = ["hello": "hi"] as CFDictionary

if let dict = maybeCast(x, to: CFDictionary.self) {
print(dict)
} else {
print("nil, or not a dict")
}

关于ios - 从 Swift 字典中检索 CGColor 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43927167/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com