带有计时器的 arc4random() 后应用程序崩溃? [复制]

Posted

技术标签:

【中文标题】带有计时器的 arc4random() 后应用程序崩溃? [复制]【英文标题】:App crashes after arc4random() with timer? [duplicate] 【发布时间】:2014-06-14 02:03:21 【问题描述】:

Swift 中,我有一个计时器。每隔一秒,屏幕上的点就会变成不同的点图像。它选择随机显示的点。这就是我想要的。该应用程序在启动时立即崩溃。就像,马上。这个崩溃是如何解决的?而且,在那之后,它会与我当前的代码一起使用吗?在注释掉一些东西并测试之后,导致它的行是imageNumber = Int(arc4random())%13 。这是如何解决的?

我的代码如下:

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    var dotChangingTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("changeDot"), userInfo: nil, repeats: true)

    var theRandomImages: UIImage[] = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen]

    openingScreenDynamicDot = theRandomImages[Int(imageNumber)]
    let finalChangingDotWelcomePage = UIImageView(image: openingScreenDynamicDot)
    finalChangingDotWelcomePage.frame = CGRectMake(110, 234, 100, 100)

func changeDot() 
    println("the images should be changing...")
    imageNumber = Int(arc4random())%13

    var theRandomImages: UIImage[] = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen]

    openingScreenDynamicDot = theRandomImages[(imageNumber)]

【问题讨论】:

调试器显示崩溃的本质是什么? 另外,首先定义您的图像数组并将计数用作模操作数!那个光秃秃的13 只是自找麻烦。 【参考方案1】:

您遇到这些崩溃是因为您尝试将 UInt32 值强制转换为 Int,而不考虑检查范围。由于UInt32 是无符号的,所以arc4random() 的一半可能返回值将超出Int 的范围,当您尝试强制转换时会出现运行时错误。做你正在做的事情的安全方法是先取模和,然后转换为Int

imageNumber = Int(arc4random() % 13)

但是,这会引入模偏差,这会影响结果的随机性,因此您最好使用:

imageNumber = Int(arc4random_uniform(13))

这两种方法都会为您提供 0 到 12 之间的随机值,包括 0 到 12。

【讨论】:

选项 2 修复了崩溃问题。虽然,它仍然不会每秒改变图像。我的代码有什么问题导致它不起作用? 生成后添加println(imageNumber)。随机并不意味着不重复 - 如果您等待的时间足够长,连续出现多个相同数字的情况并不少见。 如果有重复可以跳过一个 仍然没有改变func changeDot() println("the images should be changing...") var theRandomImages: UIImage[] = [dotOne, dotTwo, dotThree, dotFour, dotFive, dotSix, dotSeven, dotEight, dotNine, dotTen, dotEleven, dotTwelve, dotThirteen] imageNumber = Int(arc4random_uniform(13)) openingScreenDynamicDot = theRandomImages[(imageNumber)] @NateCook 您需要使用新图像更新您的UIImageView,我看不出您在viewDidLoad() 的哪个位置将UIImageView 添加到视图控制器的视图层次结构中。跨度> 【参考方案2】:

我在使用 arc4random() 时遇到了类似的神秘崩溃,并通过切换到 arc4random_uniform() 来解决它。

试试这个:

imageNumber = Int(arc4random_uniform(13))

【讨论】:

仍然出现崩溃。 是的,如果算法正确,这将无法解决问题,否则实际上会产生均匀分布(如果你可以定位 10.whatever,我认为是 10.7)

以上是关于带有计时器的 arc4random() 后应用程序崩溃? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

iOS学习day6

重新加载数组并再次添加随机值以查看

带有 CircularProgressIndicator 的倒数计时器

有没有一种方法可以使用改造来刷新带有计时器的令牌?

在带有导航应用程序的加载页面的计时器上加载插页式广告?

使用arc4random()、arc4random_uniform()取得随机数