我有一个非常奇怪的问题,我无法弄清楚这里出了什么问题。
这是我的代码
func updateSearchResultsForSearchController(searchController: UISearchController) {
filterTableData.removeAll(keepCapacity: false)
let searchWord = searchController.searchBar.text!
getCountriesNamesFromServer(searchWord)
let searchPredict = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)
newTableData = [String]()
for var i = 0; i < self.dict.count - 1; i++ {
let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String
print("countryName is \(countryName)")
newTableData.append(cityName)
}
print("newTableData is \(newTableData)" )
let array = (newTableData as NSArray).filteredArrayUsingPredicate(searchPredict)
print("array is\(array)")
filterTableData = array as! [String]
self.tableView.reloadData()
}
程序在此行崩溃
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String
当我在搜索框中输入第一个字符时,一切正常,但只要我在searchBox
程序中输入第二个字符就会崩溃并且它会给我这个错误
无法转换类型的值&#39; NSNull&#39; (0x1a03c3768)到&#39; NSString&#39; (0x1a03cd798)。
并且您的信息countryNames存在于dict
变量中,但我不知道为什么它给我空值以及为什么城市名称成功运行,因为国家/地区也存在于我所在的同一个数组中得到这个城市
更新
此行成功打印国家/地区名称
print("countryName is \(countryName)")
答案 0 :(得分:4)
好吧,他们告诉你问题是什么:你得到了NSNull类型的结果,并且NSNull 不能转换为NSString。
您很可能正在处理JSON,而JSON数据通常包含空值。
离开你的迷宫?和!
编写一些可以帮助您的代码。记住,任何!如果你没有达到你的期望,你的应用程序就会崩溃。
当你在字典中访问键“name”时,你需要处理有一个字符串的情况(很适合你),什么都没有(键不存在,非常常见),null(服务器告诉你显然没有,很常见),数字,bool,dict或数组。
对于每一种情况,请告诉我你想要的结果:崩溃?一个可选的字符串是零?一个空字符串?通常你想要一个字符串,如果它在那里,可能是一个数字转换为字符串,如果它是一个数字,如果键不存在则为nil或空字符串或null,如果你得到一个,则为崩溃或nil bool,字典或数组。
然后编写一个完全返回的函数。然后你用它。当你写(...作为?NSString)!你告诉编译器你想要崩溃,如果它不是一个字符串,那就是你得到的。
答案 1 :(得分:0)
您在此行收到了服务器上的国家/地区列表
getCountriesNamesFromServer(searchWord)
但我认为它会在没有完全设置所有数据的情况下返回一个列表。
for var i = 0; i < self.dict.count - 1; i++ {
let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String
print("countryName is \(countryName)")
newTableData.append(cityName)
}
在循环的第一次迭代中,name
值设置正确,因此它可以正常工作,但在第二次迭代中,在我看来,null
并且您无法转换NSNull
到NSString
,以便应用程序崩溃。
在转换为NSString
之前,如果您不确定服务器响应,则必须尝试字典是否包含name
密钥以及是否设置了值。如果是,你可以尝试施放它。
如果需要,您还可以使用外部库SwiftyJSON
来简化JSON
响应的解析。
答案 2 :(得分:0)
@ gnasher729讲得很好, 但是要解决您的问题,您应该使用“?”而不是“!”
所以在解析下面代码中的数据时
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as NSDictionary)!["name"] as?NSString)! as String
将代码用作
let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as? NSString)? as String ?? ""
或
let countryName = ((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as? String ?? ""
谢谢