在swift中设置UILabel.text时的EXC_BAD_INSTRUCTION

时间:2014-07-06 15:00:16

标签: ios uilabel swift exc-bad-access

我是一个快速的新手。我正在学习iOS编程The Big Nerd Ranch Guide第4版。书中的代码是objc。我正在快速翻译它们。第150页的以下代码对我不起作用。它会抛出EXC_BAD_INSTRUCTION。请问有人指出我错了吗?谢谢你的帮助。

func drawHypnoticMessage(message: NSString) {
    for i in 0..20 {
        let messageLabel = UILabel()
        messageLabel.backgroundColor = UIColor.clearColor()
        messageLabel.textColor = UIColor.whiteColor()
        messageLabel.text = message // Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode0x0)

        messageLabel.sizeToFit()

        let width = self.view.bounds.size.width - messageLabel.bounds.size.width

        let x = Int(arc4random()) % Int(width)

        let height = (self.view.bounds.size.height - messageLabel.bounds.size.height)
        let y = Int(arc4random()) % Int(height)

        var frame = messageLabel.frame
        frame.origin = CGPointMake(CGFloat(x), CGFloat(y))
        messageLabel.frame = frame

        self.view.addSubview(messageLabel)
    }
}

注意:我试过替换

messageLabel.text = message

messageLabel.text = "text"

更新1:

我找到了解决方案

func drawHypnoticMessage(message: NSString) {
    for i in 0..<20 {
        let messageLabel = UILabel()
        messageLabel.backgroundColor = UIColor.clearColor()
        messageLabel.textColor = UIColor.whiteColor()
        messageLabel.text = message

        messageLabel.sizeToFit()

        let width = self.view.bounds.size.width - messageLabel.bounds.size.width

        let x = Int(arc4random() % UInt32(width))

        let height = (self.view.bounds.size.height - messageLabel.bounds.size.height)
        let y = Int(arc4random() % UInt32(height))

        var frame = messageLabel.frame
        frame.origin = CGPointMake(CGFloat(x), CGFloat(y))
        messageLabel.frame = frame

        self.view.addSubview(messageLabel)
    }
}

基本上,我将let x = Int(arc4random()) % Int(width)更改为let x = Int(arc4random() % UInt32(width))有人知道它为什么有效吗?

更新2:

使用arc4random_uniform的最新修订:

func drawHypnoticMessage(message: NSString) {
    for i in 0..<20 {
        let messageLabel = UILabel()
        messageLabel.backgroundColor = UIColor.clearColor()
        messageLabel.textColor = UIColor.whiteColor()
        messageLabel.text = message

        messageLabel.sizeToFit()

        let width = self.view.bounds.size.width - messageLabel.bounds.size.width

        let x = CGFloat(arc4random_uniform(UInt32(width)))

        let height = (self.view.bounds.size.height - messageLabel.bounds.size.height)
        let y = CGFloat(arc4random_uniform(UInt32(height)))

        var frame = messageLabel.frame
        frame.origin = CGPointMake(x, y)
        messageLabel.frame = frame

        self.view.addSubview(messageLabel)
    }
}

2 个答案:

答案 0 :(得分:3)

根据您提供的修复程序判断,我认为问题是arc4random返回0到2之间的32位无符号整数 32 - 1.然后您将其转换为{ {1}}(我相信)是iOS中的32位有符号整数(32位模式),所以随机数的一半(2 31 和2 32 之间的那些) - 1)不能表达为Int

在新代码中,您将随机数限制为0到Int或0到width,然后尝试将其转换为height这就是为什么它不会崩溃

NB。不应使用Int,而应使用arc4random_uniform()。采用随机数的mod会引入偏差,这可以通过arc4random_uniform()来避免。

答案 1 :(得分:0)

你有没有尝试改变&#34;让messageLabel&#34; to&#34; var messageLabel&#34;?

编辑:我想纠正自己。在这种情况下,&#34;让messageLabel&#34;是宣布UILabel的正确方法。 &#34;让&#34;是常量,但是当声明&#34;让messageLabel = UILabel(),&#34;我们说UILabel的指针是不变的,而不是UILabel在声明后不能改变。