json in iOS parses the solutions of null nil NSNumber that appear

  • 2020-05-14 04:56:29
  • OfStack

In the development process of iOS, data communication with the server is often required. Json is a common efficient and concise data format.

JSON is constructed in two ways:

json is simply the object and array in javascript, so these two structures are the object and array 2 structures, through which various complex structures can be represented
1. Object: object is represented as "{}" expanded content in js, and the data structure is {key: value, key: value... In object-oriented languages, key is the property of the object, and value is the corresponding property value, so it is easy to understand that the value method is object.

2, array: array in js is the contents expanded by the brackets "[] ", and the data structure is ["java","javascript","vb"...] , the value method and all languages 1, the use of the index, the type of field value can be a number, string, array, object several.

Through the object, array 2 structures can be combined into a complex data structure.

Phenomenon of the problem

But a few projects down 1 straight encountered a pit problem, the program in the acquisition of some data after inexplicable crash. The reason was discovered early on: because some fields in the server's database are empty, this data will appear when it is returned to the client in Json form:

"somevalue":null

The data parsed through JsonKit, the third library, is

somevalue = " < null > ";

This data type is not nil or String. Once parsed into an object, if you send a message directly to the object (eg: length, count, and so on) it crashes directly. The error is:

-[NSNull length]: unrecognized selector sent to instance 0x388a4a70

The solution

In fact, 1 straight did not find a perfect solution, pit me for a long time.

1. The initial solution is to see which field may be empty in order to cope with the current crash, and judge before using the field. According to the error prompt during the crash, it can be seen that such field resolves into an object of type NSNull, so you can directly judge whether it is of this type or not:

if (![isKindOfClass:[NSNull class]]){xxxxxxx;}

Because there are too many fields, just find one to fill in one.

2. Later, in order to completely solve this problem, I planned to start from the data source. In fact, I could match the null with the regular expression, and then replace it. So we came up with a shanzhai method: string matching. When the Json returned by the server is obtained, the string object is returned when the result is returned, so the null is replaced with the null character "", and then parsed.

json = [jsonStr stringByReplacingOccurrencesOfString:@":null" withString:@":\"\""];

This method works, but my server here returns extremely terse, all kinds of garbage data... Anyway, that would make json unresolvable.

3. In the end, we have no choice but to replace the values of type NSNull with nil when parsing. Just write an tool method and call it when parsing. However, if it is too much trouble, I want to write a macro. After searching the macro surprisingly, I find that the macro can also have a return value. The result is as follows:

#define VerifyValue(value)\
({id tmp;\
if ([value isKindOfClass:[NSNull class]])\
tmp = nil;\
else\
tmp = value;\
tmp;\
})\

The last sentence of the macro is the return value. The macro is then invoked when parsing the data:

contact.contactPhone = VerifyValue(contactDic[@"send_ContactPhone"]);

4. If you use the AFNetwork library to make network requests, you can use the following code to automatically remove this annoying null value for you

self.removesKeysWithNullValues = YES;

5. The ultimate solution

Finally, I found a solution for 1 once and for all. The awesome foreigner wrote an Category, called NullSafe, which was operated at run time. He set this pesky null value to nil, and nil is safe and can send any message to nil objects without crashing. This category is very easy to use, as long as you're involved in the project, you don't have to do anything else, yeah, it's that simple. Please go to Github for details.


Related articles: