Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift数字和CGFloat(CGPoint、CGRect等)_Ios_Swift - Fatal编程技术网

Ios Swift数字和CGFloat(CGPoint、CGRect等)

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 此代码无法编译,最后一行出

我发现,当我不得不与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
此代码无法编译,最后一行出现了常见的神秘错误:

找不到接受提供的参数的“*”的重载

这个错误,我相信你们现在已经知道了,表明类型之间存在某种阻抗失配
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报告。如果这种语言继续存在,没有人会愿意使用它