我是一个快速的新手。我正在学习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)
}
}
答案 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在声明后不能改变。