在处理一些看似简单的事情时,我确实遇到了令人讨厌的错误。
我有一个NSArray
,我会在第一次启动应用时填写文字。
然后在某一点我想使用数组,所以我在类中声明了另一个数组:
var localArray = NSUserDefaults.standardUserDefaults().arrayForKey("array")!
然后我想在标签中显示一个单词。当用户按下按钮(向前/向后)时,出现下一个/前一个单词。很简单吧?它是,但不知怎的,我得到了非常讨厌的错误。
我有两种方法用于下一个/上一个词:
@IBAction func nextWord(sender: AnyObject) {
if let currentIndex = localArray.indexOf(label.text!)
{
if currentIndex == localArray.count-1
{
label.text = localArray[0] as? String
}
else
{
label.text = localArray[currentIndex+1]
}
}
}
另一种倒退的方法是相同的(必要的修改)。
在viewDidLoad
中,我只设置标签的文字:
label.text = localArray[0] as? String
问题在于if let
语句。在使用用户默认值之前,我刚刚使用几个字符串初始化localArray
。一切都很好。但是一旦我添加了用户默认值,疯狂就开始了。我在任何地方都遇到过错误localArray
说数组没有被解包。因此,在初始化本地数组时,我在用户默认数组后添加了!
。
但最后2个错误(在if let
语句中)没有任何意义。现在indexOf()
方法抛出错误,这是以前没有发生过的事情。它还告诉我它不能将字符串(label.text!)转换为@noescape (AnyObject) throws -> Bool
。
所以现在我需要将该字符串转换为NSString
才能使其工作或者什么?我发现了一些关于"桥接"与用户默认值中的数组相关。这是我的问题吗?
现在发生了什么问题:为什么我必须将数组中的字符串明确地向下转换为字符串?为什么indexOf
方法会发生变化。
不打包的可选行为不像非选择吗?
答案 0 :(得分:1)
您正在创建的对象不是数组(至少编译器不知道它是什么)。函数arrayForKey("array")!
返回AnyObject
,而不是Array
。所以从那时起,编译器认为这个对象是AnyObject
。我如何解决这个问题(可能不是正确的方法)是立即施放数组:
if let myArray: AnyObject! = NSUserDefaults.standardUserDefaults().objectForKey("array") {
//Your array exists, cast it now and use it
var localArray = myArray as! Array<String>
}
else
{
//Something bad happened, the array isn't there.
}
然后你将不得不在以后解开。如果您知道此对象将始终存在且演员阵容始终有效,您可以将?
更改为!
。
查看this answer了解更多信息。
答案 1 :(得分:0)
如果使用模运算符实现它会更好。
let newIndex = (oldIndex + 1) % localArray.count
我需要更多信息来回答您的大部分问题。 localArray
的类型是什么?
答案 2 :(得分:0)
你应该始终avoid force unwrapping optionals(并且对于大部分力量向下转发)。为了从NSUserDefaults
(使用正确的类型)安全地检索您的数组,您可以执行以下操作:
if let array = NSUserDefaults.standardUserDefaults().arrayForKey("array") as? [String] {
// do something with your [String] array
} else {
// do error handling
}
这样做的目的是从[AnyObject]?
获取NSUserDefaults
代表你的数组。然后,您可以使用as?
有条件地向下转播&amp;将它桥接回Swift数组字符串([String]
)。如果这不成功,你可以安全地处理这种可能性。