BAD_INSTRUCTION в быстром закрытии
func loadMe() -> Void {
println(me.initUrl());
let url:NSURL = NSURL(string:me.initUrl())
let request:NSURLRequest = NSURLRequest(URL:url)
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request, queue:queue, completionHandler:{response, data, error in
if data {
var jerr:NSError?
var json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error:&jerr) as NSDictionary
if !jerr {
println(json.description)
let time:String = json.valueForKey("time") as String
println(time)
// self.me.setDictionary(json)
}
}
})
}
Приведенный выше код прекрасно работает до того момента, когда я хочу присвоить значение из NSDictionary переменной.
let time:String = json.valueForKey("time") as String
сопровождается EXC_BAD_INSTRUCTION(код =EXC_I386_INVOP, субкод =0x0), но
println(json.description)
распечатывает действительный NSDictionary. Кто-нибудь знает решение этой проблемы?
2 ответа
Я решил свою проблему с приведением к правильному типу исходного значения NSDictionary после того, как понял, что не все значения NSDictionary были NSStrings. Если ваш сервис возвращает объект JSON смешанного типа, как этот
{"id":2, "name":"AC Vent Temp", ...}
вам придется получить такие значения.
var id:int = sensor.valueForKey("id") as Int;
var name:String? = sensor.valueForKey("name") as String;
valueForKey()
метод возвращает необязательное значение; Вы вводите это значение в строку и, очевидно, это вызывает сбой. Я могу заставить Swift REPL потерпеть крах с:
1> var json = ["a": "1", "b": "2"]
json: Dictionary<String, String> = {
[0] = {
key = "a"
value = "1"
}
[1] = {
key = "b"
value = "2"
}
}
2> let data:String = json["b"] as String
Bitcast requires both operands to be pointer or neither
%58 = bitcast i8* %57 to %SS.232
Bitcast requires both operands to be pointer or neither
%110 = bitcast i8* %109 to %SS.232
Stored value type does not match pointer operand type!
store %SS.232 %110, i8** %.core7._baseAddress.value, align 8
i8*LLVM ERROR: Broken function found, compilation aborted!
Assertion failed: (err == 0), function ~Mutex, file /SourceCache/lldb_KLONDIKE/lldb_KLONDIKE-320.3.100/source/Host/common/Mutex.cpp, line 246.
Abort trap: 6
Решение состоит в том, чтобы отказаться от принуждения String. В моем примере:
2> let data:String? = json["b"]
data: String? = "2"
3> let data:String? = json["c"]
data: String? = nil
Я подозреваю, что вы добавили "as String" 1) зная, что значение на самом деле является String и 2), чтобы избежать ошибки компилятора. Правильный подход заключается в использовании ?
указать необязательное значение.