In the iOS development process, often need to communicate with the server data, JSON is a commonly used efficient and concise data format.
There are two structures of JSON construction:
JSON is simply a set of objects and arrays in JavaScript, so these two structures are objects and arrays of 2 structures that can represent complex structures
1, object: The object in JS is expressed as "{}" expands content, the data structure is {Key:value,key:value,...} The structure of key-value pairs, in object-oriented language, key is the object's attribute, value is the corresponding attribute value, so it is easy to understand that the value method is the object. Key gets the value of the property, which can be a number, a string, an array, and several objects.
2, array: The array in JS is the bracketed "[]" expanded content, the data structure is ["Java", "JavaScript", "VB",...], as in all languages, the type of field value can be numbers, strings, arrays, objects, and so on.
Through the object, the array of 2 structure can be combined into a complex data structure.
Problem phenomenon
But several projects have been encountered a problem of pit Dad, the program in the acquisition of certain data after the inexplicable collapse. In fact, it was discovered early: because some of the fields in the server's database are empty, and then returned to the client in JSON, this data appears:
"somevalue": null
The data parsed by Jsonkit this third party library becomes
Somevalue = "<null>";
This data type is either nil or String. After parsing into an object, sending a message directly to the object (Eg:length,count, and so on) will crash directly. Tip Error is:
-[nsnull length]: Unrecognized selector sent to instance 0x388a4a70
Solving method
In fact, has not found the perfect solution, pit me for a long time.
1, the first solution is to cope with the current crash, to see which field may be empty, then judge the field before use, through the crash of the error hint can be seen, such a field resolved to object is Nsnull type, so you can directly determine whether this type:
if (![ Iskindofclass:[nsnull class]] {xxxxxxx;}
Because there are too many fields, find a complement.
2, then want to completely solve the problem, it is intended to start from the data source, in fact, you should be able to use regular expressions to match this null, and then replace, but it is my mishap ah. So there was a cottage. Method: String Matching. When retrieving the JSON returned by the server, the string object is returned, and the null is replaced by the null character "" before parsing.
JSON = [jsonstr stringbyreplacingoccurrencesofstring:@ ": null" withstring:@ ": \" ""];
This method would have been very effective, but my server here to return very not concise, all kinds of garbage data (do not spit this) ... Anyway, this can cause JSON to not parse.
3, finally there is no way, only in the resolution of the time, the value of the Nsnull type is replaced with nil. Usually write a tool method, and then call when parsing. But too much trouble, just want to write a macro, through the search for a surprise discovery macros can also have 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 in the macro is the return value. Then invoke the macro when parsing the data:
Contact.contactphone = Verifyvalue (contactdic[@ "Send_contactphone"));
4, if you use afnetwork this library makes the network request, may use the following code, automatically helps you to remove this nasty empty value
Self.removeskeyswithnullvalues = YES;
5, the ultimate solution
Finally found a permanent solution, the brilliant foreigner wrote a category, called Nullsafe, in the run-time operation, put this nasty null value to nil, and nil is safe, can send any message to the nil object and will not crash. This category is very convenient to use, as long as the addition to the project can be, you do not have to do anything else, yes, it is so simple. Detailed please go to the GitHub to view;