为什么以下代码在iPhone 5上崩溃而在iPhone 5S上不会?

8
func rand(max: Int?) -> Int {
    var index = Int(arc4random())
    return max? != nil ? (index % max!) : index
}

我在最后一行遇到了异常:EXC_BAD_INSTRUCTION

我猜测这可能与iPhone 5S是64位而5不是有关,但是我在上面的函数中没有看到任何涉及64位的内容?

编辑

我通过以下调整解决了问题,但我仍然无法解释为什么。

func rand(max: Int?) -> Int {
    var index = arc4random()
    return max? != nil ? Int(index % UInt32(max!)) : Int(index)
}

非常感谢,这对我很有帮助。我的应用程序也因同样的原因崩溃了。 - Rohit
2个回答

15

Int 整数类型在 iPhone 5 上是32位整数,在 5S 上是64位整数。由于 arc4random() 返回一个 UInt32,其正值范围比 iPhone 5 上的 Int 大两倍,因此你的第一版本基本上有50%的几率在这行代码上崩溃:

var index = Int(arc4random())

你修改的版本会在与 max 取模后转换,因此在那里将其安全地转换为 Int。你应该查看 arc4random_uniform,它可以处理取模操作,并避免当前实现中存在的一些偏差。


6
正如你发现的一样,arc4random返回一个无符号32位整数。所以是0到4,294,967,295。另外,Int的大小取决于它运行的系统。

引用自“Swift参考文献”

On a 32-bit platform, Int is the same size as Int32.
On a 64-bit platform, Int is the same size as Int64.
在iPhone 5上,Int类型只能保存-2,147,483,648到+2,147,483,647之间的值。在iPhone 5S上,Int类型可以保存-9,223,372,036,854,775,808到+9,223,372,036,854,775,807之间的值。无符号32位整数可以溢出Int32,但永远不会溢出Int64。
关于使用哪个随机函数以及原因,可以查看更多信息

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接