我有一个获取所有国家/地区代码的类,应该按字母顺序对它们进行排序。该类在Xcode for ios中运行良好但是当我复制它以在操场上测试时我得到一个错误。见图。
所以我删除了所有代码,发现NSMutableArray没有被正确声明,因此将其更改为。
var countries:NSMutableArray = NSMutableArray()
var countryKeys:NSMutableArray = NSMutableArray()
var countryNames:NSMutableArray = NSMutableArray()
它消除了错误,但代码不会运行。没有错误也没有输出。
任何人都知道为什么这段代码不能在游乐场中运行?这是一个错误吗?
这里的完整代码
struct countryCodes{
var countries:NSMutableArray = NSMutableArray()
var countryKeys:NSMutableArray = NSMutableArray()
var countryNames:NSMutableArray = NSMutableArray()
init(){
for code in NSLocale.ISOCountryCodes() {
let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
let name = NSLocale(localeIdentifier: "en_UK").displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
self.countries.addObject(["key":id,"value":name])
}
self.sortByValue()
}
private func sortByValue(){
let descriptor: NSSortDescriptor = NSSortDescriptor(key: "value", ascending: true)
extractToArrays(self.countries.sortedArrayUsingDescriptors([descriptor]))
}
private func extractToArrays(sortedCountries:NSArray){
for item in self.countries{
self.countryKeys.addObject(item["key"] as! String)
self.countryNames.addObject(item["value"] as! String)
}
}
}
我尝试打开一个新游乐场并立即收到错误
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
错误
file:///Volumes/External/Xcode%20Projects/MyPlayground3.playground/:错误:游乐场执行中止:执行被中断,原因:EXC_BAD_ACCESS(代码= 1,地址= 0x8)。
答案 0 :(得分:1)
一些评论。
首先,值名称应以大写字母开头:
struct CountryCodes {
避开像NSArray
和NSDictionary
这样的无类型集合。只需使用本机Swift集合类型。因此countries
将是[String : String]
:
var countries = [[String : String]]()
在初始化中,我们需要创建数组并对其进行排序。
init() {
for code in NSLocale.ISOCountryCodes() {
let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode : code])
Swift Optionals表示数据是否存在。因此,如果数据不,那么在数据模型中插入一个字符串是不好的做法。相反,使用guard
来处理这种情况:
guard let name = NSLocale(localeIdentifier: "en_UK").displayNameForKey(NSLocaleIdentifier, value: id) else {
debugPrint("Country not found for code: \(code)")
break;
}
获得密钥和值后,将它们附加到国家/地区:
countries += [["key":id, "value":name]]
}
现在你拥有所有这些,按值排序:
countries = countries.sort() { $0["value"] < $1["value"] }
}
使用map
可以快速计算密钥和国家/地区名称 - 无需将它们存储在单独的数组中:
var keys : [String] {
return countries.map { $0["key"]! }
}
var names : [String] {
return countries.map { $0["value"]! }
}
}
如果你想在操场上试试,这是完整的代码:
struct CountryCodes {
var countries = [[String : String]]()
init() {
for code in NSLocale.ISOCountryCodes() {
let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode : code])
guard let name = NSLocale(localeIdentifier: "en_UK").displayNameForKey(NSLocaleIdentifier, value: id) else {
debugPrint("Country not found for code: \(code)")
break;
}
countries += [["key":id, "value":name]]
}
countries = countries.sort() { $0["value"] < $1["value"] }
}
var keys : [String] {
return countries.map { $0["key"]! }
}
var names : [String] {
return countries.map { $0["value"]! }
}
}
let codes = CountryCodes()
codes.countries
codes.keys
codes.names
请注意,此代码不使用强制转换(as!
),因为逻辑错误导致崩溃。使用的唯一强制运算符(!
)位于keys
和names
getter中。