ios - 在 swift 中设置 UILabel.text 时的 EXC_BAD_INSTRUCTION

标签 ios uilabel swift exc-bad-access

我是一个敏捷的新手。我正在学习 iOS 编程 The Big Nerd Ranch Guide 第四版。书上的代码在objc中。我正在将它们翻译为 swift。第 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)
    }
}

最佳答案

根据您提供的修复判断,我认为问题是 arc4random 返回 0 到 232 - 1 之间的 32 位无符号整数。然后您将其转换到一个 Int ,它(我相信)是 iOS 中的 32 位有符号整数(32 位模式),所以你的随机数的一半(231 和 2 之间的随机数) >32 - 1) 不能表示为 Int

在新代码中,在尝试将随机数转换为 Int 之前,您将随机数限制为 0 到 width 或 0 到 height > 这就是它不会崩溃的原因。

注意。您应该使用 arc4random_uniform() 而不是使用 % 。取随机数的模会引入偏差,使用 arc4random_uniform() 可以避免这种偏差。

关于ios - 在 swift 中设置 UILabel.text 时的 EXC_BAD_INSTRUCTION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24597158/

相关文章:

Swift - 如何使用对象数组对表进行分组

ios - 有没有办法快速在后台线程和当前 View Controller 之间进行通信?

ios - 如何在objective-c中声明C数组属性

ios - 如何快速将文本包装在 UIButton 上

ios - 表格内的动态大小标签在 ios 中不刷新

ios - UIView 没有名为 'setTranslatesAutoresizingMaskIntoConstraints' 的成员

ios - 多个持久存储

ios - 为什么我的按钮在 iOS 模拟器中会改变填充?

ios - 如何在父 View 中获取子 UIView 的索引?

ios - 有 2 行的 UILabel,如何独立截断每行?