How could I type check CGColor / CGPath?

2019-07-21 09:08发布

问题:

So what it appears there is a filed bug for swift relating to the CoreFoundation types. Based on the description it appears there is not type checking for CGPath and CGColor, below is a snippet from the bug that demonstrates the behavior.

func check(a: AnyObject) -> Bool {
    return a is CGColor
}

check("hey") --> true
check(1.0) --> true
check(UIColor.redColor()) --> true

And here is what I'm trying to do

if let value = self.valueForKeyPath(keyPath) {
    if let currentValue = value as? CGColor {
        // Do Something with CGColor
    } else if let currentValue = value as? CGSize {
        // Do Something with CGSize
    } else  if let currentValue = value as? CGPoint {
        // Do Something with CGPoint
    }
}

I've done the following, by type checking type the types I know work first, then tagging on the last statement for AnyObject, and checking the CFTypeID. This works for now, but Apple Documentation says that the the CFTypeID can change, and should not be relied upon.

    if let currentValue = value as? CGPoint {
        // Do Something with CGPoint
    } else if let currentValue = value as? CGSize {
        // Do Something with CGSize
    } else if let currentValue = value as? AnyObject {
         if CFGetTypeID(currentValue) == 269 {
              // Cast and do Something with CGColor  
              methodCall((currentValue as! CGColor))
         }
   }

Has anyone found a reliable workaround a for this issue? As I do not want to use this hack as a long term solution

回答1:

Apple writes:

Because the value for a type ID can change from release to release, your code should not rely on stored or hard-coded type IDs nor should it hard-code any observed properties of a type ID (such as, for example, it being a small integer).

That means that you should obtain the type ID at runtime, in your case:

if CFGetTypeID(currentValue) == CGColorGetTypeID() { ... }