2

下面的代码工作得很好,但我很惊讶,因为我认为NSCache需要对象键和值,而不需要CGFloats。有人可以向我解释发生了什么吗?

class A
    var cachedPoints = NSCache()

    func rAt(theta theta: CGFloat) -> CGFloat {        
        if let r = self.cachedPoints.objectForKey(theta) as? CGFloat {
            return r
        }
        // do some very expensive maths here...
        let r = self.veryExpensiveFunction(theta)
        self.cachedPoints.setObject(r, forKey: theta)
        return r
    }
}
4

1 回答 1

2

来自“Using Swift with Cocoa and Objective-C”文档中的“使用Cocoa 数据类型”:

数字

Swift 自动桥接某些原生数字类型,例如Int and Float, to NSNumber
...
它还允许您将 type 的值传递给Int期望为NSNumber.

文档提到Int, UInt, Float, Double,Bool 作为自动桥接到的类型NSNumber,但显然这也适用CGFloat(如果导入了“Foundation”)。所以在

self.cachedPoints.setObject(r, forKey: theta)

两者rtheta都被包装到NSNumber实例中,然后传递给setObject()接受两个类型参数的方法AnyObject

在相反的方向上也有一个桥接,但记录较少(或者我找不到它)。NSNumber您可以将to CGFloat(or Int, Float, ...)的实例强制转换为

let num : NSNumber = ...
let x = num as CGFloat

结果与您在 number 实例上调用doubleValue(或floatValue,取决于体系结构)相同。在

let obj : AnyObject = ...
let y = obj as? CGFloat // CGFloat?

可以选择将该对象强制NSNumber转换为,如果成功的话,可以CGFloat像前面的示例一样转换为。

这就是发生的事情

if let r = self.cachedPoints.objectForKey(theta) as? CGFloat { ... }

如果 from 的返回值objectForKey()是 an ,NSNumber则将其转换为CGFloat并分配给r。否则,可选绑定失败。

于 2015-11-02T18:36:10.147 回答