Ios Swift数字和CGFloat(CGPoint、CGRect等)
我发现,当我不得不与Cocoa Touch就CGRect和CGPoint进行沟通时(例如,因为我们谈论的是某个东西的Ios Swift数字和CGFloat(CGPoint、CGRect等),ios,swift,Ios,Swift,我发现,当我不得不与Cocoa Touch就CGRect和CGPoint进行沟通时(例如,因为我们谈论的是某个东西的框架或边界),快速数字运算特别笨拙,这在现实生活中经常发生 CGFloat vs.Double 考虑来自UIViewController子类的以下外观无害的代码: let scale = 2.0 let r = self.view.bounds var r2 = CGRect() r2.size.width = r.size.width * scale 此代码无法编译,最后一行出
框架
或边界
),快速数字运算特别笨拙,这在现实生活中经常发生
CGFloat vs.Double
考虑来自UIViewController子类的以下外观无害的代码:
let scale = 2.0
let r = self.view.bounds
var r2 = CGRect()
r2.size.width = r.size.width * scale
此代码无法编译,最后一行出现了常见的神秘错误:
找不到接受提供的参数的“*”的重载
这个错误,我相信你们现在已经知道了,表明类型之间存在某种阻抗失配r.size.width
作为CGFloat到达,它将自动与Swift Float交换,但不能与Swift双变量交互(默认情况下,它是scale
的值)
这个例子人为地简单,所以有一个人为地简单的解决方案,就是从一开始就将scale
转换为Float。但是,当从各地抽取的许多变量都涉及到一个建议的CGRect元素的计算时,有很多铸造工作要做
详细初始值设定项
另一个恼人的问题是当创建新的CGRect时会发生什么。尽管有文档,但没有带值但没有标签的初始值设定项。这无法编译,因为我们有两个:
let d = 2.0
var r3 = CGRect(d, d, d, d)
但即使我们将d
转换为浮点,我们也不会编译:
调用中缺少参数标签“x:y:width:height:”
因此,我们最终回到了CGRectMake
,这对Objective-C没有任何改进。有时CGRectMake和CGSizeMake也没有改进。从我的一个应用程序中考虑这个实际代码:
let kSEP : Float = 2.0
let intercellSpacing = CGSizeMake(kSEP, kSEP);
在我的一个项目中,这很有效。在另一个例子中,它神秘地失败了——完全相同的代码出现此错误时:
“NSNumber”不是“CGFloat”的子类型
有时,斯威夫特试图通过向NSNumber施放一个浮点来“跨越桥梁”,当桥的另一边需要一个CGFloat时,这当然是错误的。我还没有弄清楚这两个项目之间的区别是什么,导致错误出现在一个项目中,而不是另一个项目中(可能是其他人)
注意:我可能已经解决了这个问题:它似乎取决于仅构建活动体系结构的构建设置,这反过来又表明这是一个64位问题。这是有道理的,因为在64位设备上,Float与CGFloat不匹配。这意味着阻抗失配问题比我想象的还要严重
结论
我在寻找关于这个话题的实用智慧之词。我想可能有人设计了一些CGRect和CGPoint扩展,这会让生活变得更轻松。(或者可能有人编写了大量额外的算术运算符函数重载,这样,如果可能的话,将CGFloat与Int或Double结合起来“就行了”)如您所发现的,显式键入
scale
到CGFloat
,确实是swift处理键入问题的方法。供他人参考:
let scale: CGFloat = 2.0
let r = self.view.bounds
var r2 = CGRect()
r2.size.width = r.width * scale
不知道如何回答你的第二个问题,你可能想用不同的标题单独发布
更新:
Swift创始人兼首席开发者Chris Lattner在2014年7月4日的新闻发布会上发表了以下言论:
这里发生的是CGFloat是这两个Float的类型别名
或者加倍,这取决于您是构建32位还是64位。
这正是Objective-C的工作原理,但在Swift中存在问题
因为Swift不允许隐式转换
我们知道
这个问题,并认为它是严重的:我们正在评估几个
目前有不同的解决方案,将在稍后的测试版中推出。
正如你所注意到的,今天你可以通过加倍施法来解决这个问题。
这是不雅但有效的:-)
在Xcode 6 Beta 5中更新:
CGFloat可以从任何整数类型(包括
已调整大小的整数类型),反之亦然。(17670817)
我为Double和Int创建了一个扩展,它向它们添加了一个计算CGFloatValue属性
extension Double {
var CGFloatValue: CGFloat {
get {
return CGFloat(self)
}
}
}
extension Int {
var CGFloatValue: CGFloat {
get {
return CGFloat(self)
}
}
}
您可以使用let someCGFloat=someDoubleOrInt.CGFloatValue
另外,对于CGRect初始值设定项,您会得到缺少参数标签的错误,因为您已经删除了标签,您需要
CGRect(x:d,y:d,width:d,height:d)
除非只有一个参数,否则您不能忽略标签。我编写了一个处理运算符重载的库,以允许Int之间的交互,CGFloat和Double
从Beta 5开始,这里列出了你目前无法使用vanilla Swift进行的操作。
我建议运行带有和不带有ScalarArithmetic的测试套件,看看发生了什么 撇开个人偏好不谈,这就是swift处理打字问题的方式。苹果正在寻找关于这门语言的反馈,所以我相信他们会愿意收到一些关于这门语言的反馈。使用
CGFloat
s时,必须将所有内容键入CGFloat
。很简单。@Sulthan是的,但问题是当你说“一切”时,你实际上是指“一切”。例如,如果f
是CGFloat,而d
是Double(这是默认值),则不能将它们相乘。因此,正如我在我的问题中所说的,有很多演员要做。“但那是胡说八道,”苏尔坦说,“我有一个bug。在Objective-C中,一旦某个对象是CGFloat,所有数值操作都可以正常工作,并且与CGRect和CGPoint的信息交换在32位和64位平台上都可以正常工作。毕竟,如果没有iOS编程中最常见的需求之一的易用性,这种语言将非常难以使用。@Sulthan我没有说这是一个bug,我说我提交了一份bug报告。如果这种语言继续存在,没有人会愿意使用它