带有 `\(var)` 的字符串会导致“展开可选值”错误

Posted

技术标签:

【中文标题】带有 `\\(var)` 的字符串会导致“展开可选值”错误【英文标题】:String with `\(var)` causes "unwrapping an optional value" error带有 `\(var)` 的字符串会导致“展开可选值”错误 【发布时间】:2015-03-09 00:59:08 【问题描述】:

我有一个这样的循环,它创建一个代表 url 的字符串:

    for(var i = 1; i < 6; i++)
    
        let urlString: String = "http://.../data/\(i).txt"
        var downloader = FileDownloader(url: urlString, array: peopleArray, table: theTable)

        downloaderQueue.addOperation(downloader)
    

FileDownloader构造函数如下:

let urlString: String
var personArray: Array<Person> = []
var person: Person
let table: UITableView

init(url: String, array: Array<Person>, table: UITableView)

    self.urlString = url
    self.person = Person()
    self.personArray = array
    self.table = table

当这段代码运行时,lldb 给我错误:

fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) 

而且我知道问题出在调试器输出的字符串上:

downloader  Lecture_14.FileDownloader   0x000000016fd89f60  0x000000016fd89f60
    Foundation.NSOperation  NSOperation     
    urlString   String  "unexpectedly found nil while unwrapping an Optional value" 
        _core   _StringCore

任何想法为什么会发生这种情况?

【问题讨论】:

哪一行代码失败了? var downloader = ... 我不知道 Swift,但对我来说,该错误表明您正在尝试从选项容器中取出一个值,而没有先检查操作是否失败。选项类型用于表示可能失败的操作,并且将返回包装结果或失败对象。如果你尝试解开失败对象(nil?),你会得到一个异常。如果是这种情况,您需要根据结果进行模式匹配并说明失败的原因。 【参考方案1】:

在 Xcode 中,选择并单击每个正在使用的变量:urlString、peopleArray 和 theTable。

出现的弹出窗口将通过附加一个 ? 来显示该变量是否为可选变量。到类名。

从上面的代码中,urlString 不应该是可选的,因此不应该是问题。但是请检查其他正在使用的变量,看看它们是否是可选的。

如果是这样,请使用以下内容:

if let checkedPeopleArray = peopleArray 
   // now you can use checkedPeopleArray and be sure it is not nil

让您的代码更像 Swift 的其他几点:

您的循环可以这样编写,使用 Swift 的范围而不是传统的 C 样式循环:

for i in 1..<6 
    let urlString: String = "http://.../data/\(i).txt"

在声明数组时,Apple 从 Swift 的第一个版本改变了这一点。而不是:

var personArray: Array<Person> = []

尝试:

var personArray: [Person]()  // empty array for Person objects

在你的初始化中:

init(url: String, array: [Person], table: UITableView)

功能相同,但我觉得最好使用语言的更改,因为不知道 Apple 何时/是否会删除旧语法。

【讨论】:

感谢您的风格提示。问题似乎是theTable。我需要能够从我正在运行的 NSOperation 线程重新加载表数据。有没有比传递 UITableView 实例更好的方法? 向您的 FileDownloader 类添加一个委托协议怎么样?当它为表准备好数据时,它可以将其发送给其委托以重新加载表。

以上是关于带有 `\(var)` 的字符串会导致“展开可选值”错误的主要内容,如果未能解决你的问题,请参考以下文章

致命错误:在展开可选值时意外发现 nil - 带有 NSURLRequest 的 Swift

UITableViewCell 中的 AVPlayer 导致“在隐式展开可选值时意外发现 nil”错误

将展开的值传递给 Text() 成功,但传递给 Link() 会导致“在展开可选值时意外发现 nil”

在展开可选值时发现 nil

Alamofire:在展开可选值时意外发现 nil

致命错误:将可选值 TableViewCell 展开到 UIViewController 时发现 Nil