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

Sno*_*man 8 swift

func rand(max: Int?) -> Int {
    var index = Int(arc4random())
    return max? != nil ? (index % max!) : index
}
Run Code Online (Sandbox Code Playgroud)

我在最后一行得到一个例外: 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)
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ook 15

Int整数类型是在iPhone 5 32位整数,在一个5S 64位整数.因为arc4random()返回a UInt32,它Int是iPhone 5 正面范围的两倍,你的第一个版本基本上有50%的几率崩溃在这一行:

var index = Int(arc4random())
Run Code Online (Sandbox Code Playgroud)

您的修改版本等待转换,直到您使用模数和max,因此转换到Int那里是安全的.您应该查看arc4random_uniform,它为您处理模数并避免当前实现中固有的偏差.


san*_*anz 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.
Run Code Online (Sandbox Code Playgroud)

在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.

有关使用哪种随机函数以及原因的更多信息.