NSJSONSerialization无法解析有效的JSON-“垃圾末" [英] NSJSONSerialization Fails to Parse Valid JSON - "Garbage at End"

查看:178
本文介绍了NSJSONSerialization无法解析有效的JSON-“垃圾末"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的iOS程序正在接收JSON数据并尝试解析它,但由于我无法确定的某些原因而总是失败.多个线程几乎同时调用此函数.奇怪的是,这只有在我切换到使用GCDAsyncSocket后才开始发生.这是用于接收和解析数据的相关代码:

My iOS program is receiving JSON data and trying to parse it but always fails for some reason I cannot determine. Multiple threads are calling this function almost at the same time. This only started happening once I switched to using GCDAsyncSocket, strangely. Here is the relevant code for receiving and parsing data:

// Called whenever I want my program to receive null-terminated data from the server:
[socket readDataToData:[NSData dataWithBytes:"\0" length:1] withTimeout:10 tag:0];

- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag{ // a GCDAsyncSocket delegate method
    [self didReceiveNetworkData:data];
}

- (void)didReceiveNetworkData: (NSData*) data{
    if (TESTING) NSLog(@"Received network data of length %lu===\n%@\n===", (unsigned long) data.length, [[NSString alloc] initWithData: data encoding:NSUTF8StringEncoding]);
    NSError* error;
    NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData: data
                          options:kNilOptions
                          error:&error];
    if (!json){
        NSLog(@"Got an error parsing received JSON data: %@", error);
        return;
    }
    // Then I handle the dictionary (omitted code)…
}

日志和断点调试器说这是接收到的数据:

The log and breakpoint debugger say that this is the data received:

{
"responseType": -1
}

确切地说,其字节为"{\ n \ t \" responseType \":\ t-1 \ n} \ 0".一旦运行JSONObjectWithData函数,我就会收到此垃圾结尾"错误:

To be exact, its bytes are "{\n\t\"responseType\":\t-1\n}\0". And I get this "garbage at end" error once the JSONObjectWithData function runs:

Got an error parsing received JSON data: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Garbage at end.) UserInfo=0x10b203800 {NSDebugDescription=Garbage at end.}

根据在线JSON测试人员和我自己在单独项目中的简单测试,这是有效的JSON.那我为什么会出错呢?我以为它可能是在抱怨空终止符之后有多余的字节,所以我尝试通过将其制成NSString并将其变回NSData来对其进行修整,但这无济于事:

According to online JSON testers and my own simple test in a separate project, this is valid JSON. So why am I getting an error? I thought that maybe it was complaining about extra bytes after the null terminator, so I tried trimming it by making an NSString out of it then turning that back into NSData, but that did not help:

NSDictionary* json = [NSJSONSerialization
                      JSONObjectWithData: [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] dataUsingEncoding: NSUTF8StringEncoding]
                      options:kNilOptions
                      error:&error];

因为使用GCDAsyncSocket是导致此问题的原因,所以我想知道它是否与多线程有关,但是我真的不认为这有什么重要的原因.有什么想法吗?

Because using GCDAsyncSocket is what started this problem, I'm wondering if it has to do with multithreading, but I really cannot think of any reason why that would matter. Any ideas?

P.S.我之所以使用GCDAsyncSocket,是因为我不知道如何处理Objective-C中的低级套接字,因此我的原始代码有很多怪异的错误.

P.S. I'm using GCDAsyncSocket because I don't know how to deal with low-level sockets in Objective-C, so my original code had tons of weird bugs.

推荐答案

更新: 您可能在某种程度上遇到了转义字符的问题.我自己不是JSON专家,但我记得我曾经将JSON字符串添加到字典中,然后根据该字典创建了JSON. JSON字符串本身变成了转义符,因此在解析期间它将保留为字符串.我的感觉是您需要删除转义字符.

Update: You are probably having a problem somehow with the escape characters. I am no JSON guru myself, but I remember that I once had a JSON string added into an dictionary and then created a JSON from that dictionary. The JSON string itself became escapes, so it would stay a string during parsing. My feeling is you need to remove the escape characters.

也许您有一些竞争条件,并且在进行JSONParsing时正在写入数据.确保将NSData而不是NSMutableData传递给执行序列化的方法以确保. 请记住,NSJSONSerialization不是流JSON解析器.它接受一个不可变的JSON对象,并将其序列化为Foundation对象.如果您要向NSData添加字节,则NSJSONSerialization会在某个时候看到字节流,该字节流在那个时候不是有效的JSON(还).

Maybe you have some race condition and are writing to the data while the JSONParsing is ongoing. Make sure you are passing NSData and not NSMutableData to the method that does the serialization to make sure. Remember that NSJSONSerialization is not a streaming JSON parser. It takes an immutable JSON object and serializes that into a Foundation object. If you are adding bytes to the NSData, NSJSONSerialization will see at some point stream of bytes that at that point is not valid JSON (yet).

这篇关于NSJSONSerialization无法解析有效的JSON-“垃圾末"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆