无法将 'NSNull' 类型的值转换为 'NSString'
Could not cast value of type 'NSNull' to 'NSString'
我遇到了一个非常奇怪的问题,我无法弄清楚这里出了什么问题。
这是我的代码
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
程序中键入第二个字符时,它立即崩溃并给我这个错误
无法将类型 'NSNull' (0x1a03c3768) 的值转换为 'NSString' (0x1a03cd798)。
并且为了您的信息,countryNames 存在于 dict
变量中,但我不知道为什么它给我 null 值以及为什么城市名称能够成功工作,因为 country 也存在于我所在的同一个数组中获取城市
更新:
这一行打印国家名称成功
print("countryName is \(countryName)")
好吧,他们告诉你问题出在哪里:你得到了一个 NSNull 类型的结果,而 NSNull 不能 转换为 NSString。
您很可能正在处理 JSON,并且 JSON 数据通常包含空值。
离开你的迷宫?和 !
写一些对你有帮助的代码。记住任何!如果您没有得到您期望的结果,将会使您的应用程序崩溃。
当你访问字典中的键 "name" 时,你需要处理以下情况:有一个字符串(对你来说很好),没有(键不存在,很常见),空(服务器明确告诉你什么都没有,很常见),一个数字,bool,dict 或数组。
对于每种情况,请告诉我您想要的结果是什么:崩溃?一个可选的字符串是 nil?一个空字符串?通常,如果它存在,您需要一个字符串,如果它是一个数字,则可能需要一个数字转换为字符串,如果键不存在或为 null,则可能是 nil 或一个空字符串,如果您得到一个崩溃或 nil布尔值、字典或数组。
然后写一个 returns 完全一样的函数。然后你使用它。当你写 (... as?NSString) 时!你告诉编译器如果它不是字符串你想要崩溃,这就是你得到的。
您在这一行收到了来自服务器的国家/地区列表
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
响应的解析。
@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 ?? ""
谢谢
我遇到了一个非常奇怪的问题,我无法弄清楚这里出了什么问题。
这是我的代码
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
程序中键入第二个字符时,它立即崩溃并给我这个错误
无法将类型 'NSNull' (0x1a03c3768) 的值转换为 'NSString' (0x1a03cd798)。
并且为了您的信息,countryNames 存在于 dict
变量中,但我不知道为什么它给我 null 值以及为什么城市名称能够成功工作,因为 country 也存在于我所在的同一个数组中获取城市
更新:
这一行打印国家名称成功
print("countryName is \(countryName)")
好吧,他们告诉你问题出在哪里:你得到了一个 NSNull 类型的结果,而 NSNull 不能 转换为 NSString。
您很可能正在处理 JSON,并且 JSON 数据通常包含空值。
离开你的迷宫?和 !
写一些对你有帮助的代码。记住任何!如果您没有得到您期望的结果,将会使您的应用程序崩溃。
当你访问字典中的键 "name" 时,你需要处理以下情况:有一个字符串(对你来说很好),没有(键不存在,很常见),空(服务器明确告诉你什么都没有,很常见),一个数字,bool,dict 或数组。
对于每种情况,请告诉我您想要的结果是什么:崩溃?一个可选的字符串是 nil?一个空字符串?通常,如果它存在,您需要一个字符串,如果它是一个数字,则可能需要一个数字转换为字符串,如果键不存在或为 null,则可能是 nil 或一个空字符串,如果您得到一个崩溃或 nil布尔值、字典或数组。
然后写一个 returns 完全一样的函数。然后你使用它。当你写 (... as?NSString) 时!你告诉编译器如果它不是字符串你想要崩溃,这就是你得到的。
您在这一行收到了来自服务器的国家/地区列表
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
响应的解析。
@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 ?? ""
谢谢