操场上的NSMutableArray导致Xcode 7

时间:2015-09-15 15:01:31

标签: ios swift xcode7 swift-playground

我有一个获取所有国家/地区代码的类,应该按字母顺序对它们进行排序。该类在Xcode for ios中运行良好但是当我复制它以在操场上测试时我得到一个错误。见图。

Playground code

所以我删除了所有代码,发现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)。

1 个答案:

答案 0 :(得分:1)

一些评论。

首先,值名称应以大写字母开头:

struct CountryCodes {

避开像NSArrayNSDictionary这样的无类型集合。只需使用本机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!),因为逻辑错误导致崩溃。使用的唯一强制运算符(!)位于keysnames getter中。