我正在观看WWDC2014上的一些视频并尝试编写我喜欢的代码,但我注意到的一个奇怪的事情是Swift一直对我生气并希望我投射到不同的数字类型.这很容易,但在WWDC的视频中他们不需要这样做.以下是"Interface Builder的新功能"中的示例:
-M_PI/2一直给我错误:"无法找到接受提供的参数的'/'的重载'
有没有人有这个问题的解决方案,这不仅仅涉及投射,因为有明显的另一种方式这样做?对于类似的问题,我有很多例子.
if !ringLayer {
ringLayer = CAShapeLayer()
let innerRect = CGRectInset(bounds, lineWidth / 2.0, lineWidth / 2.0)
let innerPath = UIBezierPath(ovalInRect: innerRect)
ringLayer.path = innerPath.CGPath
ringLayer.fillColor = nil
ringLayer.lineWidth = lineWidth
ringLayer.strokeColor = UIColor.blueColor().CGColor
ringLayer.anchorPoint = CGPointMake(0.5, 0.5)
ringLayer.transform = CATransform3DRotate
(ringLayer.transform, -M_PI/2, 0, 0, 1)
layer.addSublayer(ringLayer)
}
ringLayer.frame = layer.bounds
Run Code Online (Sandbox Code Playgroud)
编辑:NB:CGFloat在beta 4中发生了变化,特别是为了更容易处理这个32/64位差异.阅读发行说明,现在不要将下面作为福音:它是为beta 2编写的.
在得出这个答案的线索后,我已经解决了这个问题:它取决于所选的项目架构.如果我将Project架构保留为默认值(armv7,arm64),那么我会得到与此代码相同的错误:
// Error with arm7 target:
ringLayer.transform = CATransform3DRotate(ringLayer.transform, -M_PI/2, 0, 0, 1)
Run Code Online (Sandbox Code Playgroud)
...并且需要投射到Float(好吧,下面的CGFloat,我敢肯定)让它工作:
// Works with explicit cast on arm7 target
ringLayer.transform = CATransform3DRotate(ringLayer.transform, Float(-M_PI/2), 0, 0, 1)
Run Code Online (Sandbox Code Playgroud)
但是,如果我仅将目标体系结构更改为arm64,则代码的工作方式与Apple视频中的视频一样:
// Works fine with arm64 target:
ringLayer.transform = CATransform3DRotate(ringLayer.transform, -M_PI/2, 0, 0, 1)
Run Code Online (Sandbox Code Playgroud)
所以为了回答你的问题,我相信这是因为CGFloat被定义为64位架构的双倍,因此可以使用M_PI(也是一个双倍)来源的值作为CGFloat参数.但是,当arm7是目标时,CGFloat是一个浮点数,而不是一个双精度数,因此当将M_PI(仍为双精度)表达式直接作为CGFloat参数传递时,您将失去精度.
请注意,Xcode默认只为Debug版本的"主动"架构构建 - 我发现可以通过在Xcode菜单栏的标准下拉列表中切换iPhone 4S和iPhone 5S方案来切换此错误,如他们有不同的架构.我想在演示视频中,选择了64位架构目标,但在您的项目中,您选择了32位架构?
鉴于CGFloat在64位体系结构上是双精度的,处理这个特定问题的最简单方法是始终转换为CGFloat.
但是,当您需要在不同的体系结构上执行不同的操作时,作为处理此类问题的演示,Swift确实支持条件编译:
#if arch(x86_64) || arch(arm64)
ringLayer.transform = CATransform3DRotate (ringLayer.transform, -M_PI / 2, 0, 0, 1)
#else
ringLayer.transform = CATransform3DRotate (ringLayer.transform, CGFloat(-M_PI / 2), 0, 0, 1)
#endif
Run Code Online (Sandbox Code Playgroud)
然而,这只是一个例子.你真的不想在这个地方做这种事情,所以我当然坚持只使用CGFloat(<whatever POSIX double value you need>)32位或64位值取决于目标架构.
苹果添加了更多的帮助来处理后面的编译器的不同版本的彩车,例如,在早期测试版,你可以不拿floor()单精度浮点数的容易,而现在(目前的Xcode 6.1)有要替换的floor(),ceil()等.对于float和double,所以你不需要摆弄条件编译.
| 归档时间: |
|
| 查看次数: |
2257 次 |
| 最近记录: |