由于项目不得不用到json来解析服务器端传来的数据,于是不得不选择一种在unity3d上面可用的json.开始根据网上推荐LitJson,于是下载下来源码,导入项目;

经过测试可以用;但是移植到ipad时,就各种问题了,上网查问题也没结果,就发现有人说JsonMapper is not compatible with IOS,太坑爹不兼容。

于是又根据网友推荐的MiniJson,功能虽然没有litjson强大,不能够解析嵌套数组,但是可以满足自己现在的需求。最终经过两天的挣扎,测试litjson无法可用,选择了MiniJson. (测试期间还接触了jsonfx,但是导入项目时出错,就不折腾了)

MiniJson下载:

https://gist.github.com/darktable/1411710

MiniJson测试代码:

using MiniJson;

  1. void Start ()
  2. {
  3.  
  4. string jsonString = "{ \"array\": [1.44,22,33]" +
  5. "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
  6. "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
  7. "\"unicode\": \"\\u3041 Men\\u00fa sesi\\u00f3n\", " +
  8. "\"int\": 65536, " +
  9. "\"float\": 3.1415926, " +
  10. "\"bool\": true, " +
  11. "\"null\": null }";
  12.  
  13. //Dictionary<string, object> dict = MiniJSON.LC_MiniJson.Deserialize(jsonString) as Dictionary.<string. Object>;
  14. Dictionary<string, object> dict = MiniJSON.LC_MiniJson.Deserialize(jsonString) as Dictionary<string, object>;
  15. Debug.Log("deserialized: " + dict.GetType());
  16.  
  17. //double[][] arrayList = MiniJSON.LC_MiniJson.Deserialize((dict["array"] as List<object>)[0].ToString()) as double[][];
  18.  
  19. List<object> lst = (List<object>) dict["array"];
  20.  
  21. Debug.Log("dict['array'][0]: "+ lst[2]);
  22.  
  23. Debug.Log("dict['string']: " + dict["string"].ToString());
  24. Debug.Log("dict['float']: " + dict["float"]); // floats come out as doubles
  25. Debug.Log("dict['int']: " + dict["int"]); // ints come out as longs
  26. Debug.Log("dict['unicode']: " + dict["unicode"].ToString());
  27.  
  28. Dictionary<string, object> dict2 = (dict["object"]) as Dictionary<string, object>;
  29.  
  30. string str = MiniJSON.LC_MiniJson.Serialize(dict2);
  31.  
  32. Debug.Log("serialized: " + str);
  33. }
  1. /*
  2. * Copyright (c) 2013 Calvin Rien
  3. *
  4. * Based on the JSON parser by Patrick van Bergen
  5. * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
  6. *
  7. * Simplified it so that it doesn't throw exceptions
  8. * and can be used in Unity iPhone with maximum code stripping.
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining
  11. * a copy of this software and associated documentation files (the
  12. * "Software"), to deal in the Software without restriction, including
  13. * without limitation the rights to use, copy, modify, merge, publish,
  14. * distribute, sublicense, and/or sell copies of the Software, and to
  15. * permit persons to whom the Software is furnished to do so, subject to
  16. * the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be
  19. * included in all copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  24. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  25. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  26. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  27. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. */
  29. using System;
  30. using System.Collections;
  31. using System.Collections.Generic;
  32. using System.IO;
  33. using System.Text;
  34.  
  35. namespace MiniJSON {
  36. // Example usage:
  37. //
  38. // using UnityEngine;
  39. // using System.Collections;
  40. // using System.Collections.Generic;
  41. // using MiniJSON;
  42. //
  43. // public class MiniJSONTest : MonoBehaviour {
  44. // void Start () {
  45. // var jsonString = "{ \"array\": [1.44,2,3], " +
  46. // "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
  47. // "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
  48. // "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
  49. // "\"int\": 65536, " +
  50. // "\"float\": 3.1415926, " +
  51. // "\"bool\": true, " +
  52. // "\"null\": null }";
  53. //
  54. // var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
  55. //
  56. // Debug.Log("deserialized: " + dict.GetType());
  57. // Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
  58. // Debug.Log("dict['string']: " + (string) dict["string"]);
  59. // Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
  60. // Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
  61. // Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
  62. //
  63. // var str = Json.Serialize(dict);
  64. //
  65. // Debug.Log("serialized: " + str);
  66. // }
  67. // }
  68.  
  69. /// <summary>
  70. /// This class encodes and decodes JSON strings.
  71. /// Spec. details, see http://www.json.org/
  72. ///
  73. /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
  74. /// All numbers are parsed to doubles.
  75. /// </summary>
  76. public static class Json {
  77. /// <summary>
  78. /// Parses the string json into a value
  79. /// </summary>
  80. /// <param name="json">A JSON string.</param>
  81. /// <returns>An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false</returns>
  82. public static object Deserialize(string json) {
  83. // save the string for debug information
  84. if (json == null) {
  85. return null;
  86. }
  87.  
  88. return Parser.Parse(json);
  89. }
  90.  
  91. sealed class Parser : IDisposable {
  92. const string WORD_BREAK = "{}[],:\"";
  93.  
  94. public static bool IsWordBreak(char c) {
  95. return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
  96. }
  97.  
  98. enum TOKEN {
  99. NONE,
  100. CURLY_OPEN,
  101. CURLY_CLOSE,
  102. SQUARED_OPEN,
  103. SQUARED_CLOSE,
  104. COLON,
  105. COMMA,
  106. STRING,
  107. NUMBER,
  108. TRUE,
  109. FALSE,
  110. NULL
  111. };
  112.  
  113. StringReader json;
  114.  
  115. Parser(string jsonString) {
  116. json = new StringReader(jsonString);
  117. }
  118.  
  119. public static object Parse(string jsonString) {
  120. using (var instance = new Parser(jsonString)) {
  121. return instance.ParseValue();
  122. }
  123. }
  124.  
  125. public void Dispose() {
  126. json.Dispose();
  127. json = null;
  128. }
  129.  
  130. Dictionary<string, object> ParseObject() {
  131. Dictionary<string, object> table = new Dictionary<string, object>();
  132.  
  133. // ditch opening brace
  134. json.Read();
  135.  
  136. // {
  137. while (true) {
  138. switch (NextToken) {
  139. case TOKEN.NONE:
  140. return null;
  141. case TOKEN.COMMA:
  142. continue;
  143. case TOKEN.CURLY_CLOSE:
  144. return table;
  145. default:
  146. // name
  147. string name = ParseString();
  148. if (name == null) {
  149. return null;
  150. }
  151.  
  152. // :
  153. if (NextToken != TOKEN.COLON) {
  154. return null;
  155. }
  156. // ditch the colon
  157. json.Read();
  158.  
  159. // value
  160. table[name] = ParseValue();
  161. break;
  162. }
  163. }
  164. }
  165.  
  166. List<object> ParseArray() {
  167. List<object> array = new List<object>();
  168.  
  169. // ditch opening bracket
  170. json.Read();
  171.  
  172. // [
  173. var parsing = true;
  174. while (parsing) {
  175. TOKEN nextToken = NextToken;
  176.  
  177. switch (nextToken) {
  178. case TOKEN.NONE:
  179. return null;
  180. case TOKEN.COMMA:
  181. continue;
  182. case TOKEN.SQUARED_CLOSE:
  183. parsing = false;
  184. break;
  185. default:
  186. object value = ParseByToken(nextToken);
  187.  
  188. array.Add(value);
  189. break;
  190. }
  191. }
  192.  
  193. return array;
  194. }
  195.  
  196. object ParseValue() {
  197. TOKEN nextToken = NextToken;
  198. return ParseByToken(nextToken);
  199. }
  200.  
  201. object ParseByToken(TOKEN token) {
  202. switch (token) {
  203. case TOKEN.STRING:
  204. return ParseString();
  205. case TOKEN.NUMBER:
  206. return ParseNumber();
  207. case TOKEN.CURLY_OPEN:
  208. return ParseObject();
  209. case TOKEN.SQUARED_OPEN:
  210. return ParseArray();
  211. case TOKEN.TRUE:
  212. return true;
  213. case TOKEN.FALSE:
  214. return false;
  215. case TOKEN.NULL:
  216. return null;
  217. default:
  218. return null;
  219. }
  220. }
  221.  
  222. string ParseString() {
  223. StringBuilder s = new StringBuilder();
  224. char c;
  225.  
  226. // ditch opening quote
  227. json.Read();
  228.  
  229. bool parsing = true;
  230. while (parsing) {
  231.  
  232. if (json.Peek() == -1) {
  233. parsing = false;
  234. break;
  235. }
  236.  
  237. c = NextChar;
  238. switch (c) {
  239. case '"':
  240. parsing = false;
  241. break;
  242. case '\\':
  243. if (json.Peek() == -1) {
  244. parsing = false;
  245. break;
  246. }
  247.  
  248. c = NextChar;
  249. switch (c) {
  250. case '"':
  251. case '\\':
  252. case '/':
  253. s.Append(c);
  254. break;
  255. case 'b':
  256. s.Append('\b');
  257. break;
  258. case 'f':
  259. s.Append('\f');
  260. break;
  261. case 'n':
  262. s.Append('\n');
  263. break;
  264. case 'r':
  265. s.Append('\r');
  266. break;
  267. case 't':
  268. s.Append('\t');
  269. break;
  270. case 'u':
  271. var hex = new char[4];
  272.  
  273. for (int i=0; i< 4; i++) {
  274. hex[i] = NextChar;
  275. }
  276.  
  277. s.Append((char) Convert.ToInt32(new string(hex), 16));
  278. break;
  279. }
  280. break;
  281. default:
  282. s.Append(c);
  283. break;
  284. }
  285. }
  286.  
  287. return s.ToString();
  288. }
  289.  
  290. object ParseNumber() {
  291. string number = NextWord;
  292.  
  293. if (number.IndexOf('.') == -1) {
  294. long parsedInt;
  295. Int64.TryParse(number, out parsedInt);
  296. return parsedInt;
  297. }
  298.  
  299. double parsedDouble;
  300. Double.TryParse(number, out parsedDouble);
  301. return parsedDouble;
  302. }
  303.  
  304. void EatWhitespace() {
  305. while (Char.IsWhiteSpace(PeekChar)) {
  306. json.Read();
  307.  
  308. if (json.Peek() == -1) {
  309. break;
  310. }
  311. }
  312. }
  313.  
  314. char PeekChar {
  315. get {
  316. return Convert.ToChar(json.Peek());
  317. }
  318. }
  319.  
  320. char NextChar {
  321. get {
  322. return Convert.ToChar(json.Read());
  323. }
  324. }
  325.  
  326. string NextWord {
  327. get {
  328. StringBuilder word = new StringBuilder();
  329.  
  330. while (!IsWordBreak(PeekChar)) {
  331. word.Append(NextChar);
  332.  
  333. if (json.Peek() == -1) {
  334. break;
  335. }
  336. }
  337.  
  338. return word.ToString();
  339. }
  340. }
  341.  
  342. TOKEN NextToken {
  343. get {
  344. EatWhitespace();
  345.  
  346. if (json.Peek() == -1) {
  347. return TOKEN.NONE;
  348. }
  349.  
  350. switch (PeekChar) {
  351. case '{':
  352. return TOKEN.CURLY_OPEN;
  353. case '}':
  354. json.Read();
  355. return TOKEN.CURLY_CLOSE;
  356. case '[':
  357. return TOKEN.SQUARED_OPEN;
  358. case ']':
  359. json.Read();
  360. return TOKEN.SQUARED_CLOSE;
  361. case ',':
  362. json.Read();
  363. return TOKEN.COMMA;
  364. case '"':
  365. return TOKEN.STRING;
  366. case ':':
  367. return TOKEN.COLON;
  368. case '0':
  369. case '1':
  370. case '2':
  371. case '3':
  372. case '4':
  373. case '5':
  374. case '6':
  375. case '7':
  376. case '8':
  377. case '9':
  378. case '-':
  379. return TOKEN.NUMBER;
  380. }
  381.  
  382. switch (NextWord) {
  383. case "false":
  384. return TOKEN.FALSE;
  385. case "true":
  386. return TOKEN.TRUE;
  387. case "null":
  388. return TOKEN.NULL;
  389. }
  390.  
  391. return TOKEN.NONE;
  392. }
  393. }
  394. }
  395.  
  396. /// <summary>
  397. /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
  398. /// </summary>
  399. /// <param name="json">A Dictionary<string, object> / List<object></param>
  400. /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
  401. public static string Serialize(object obj) {
  402. return Serializer.Serialize(obj);
  403. }
  404.  
  405. sealed class Serializer {
  406. StringBuilder builder;
  407.  
  408. Serializer() {
  409. builder = new StringBuilder();
  410. }
  411.  
  412. public static string Serialize(object obj) {
  413. var instance = new Serializer();
  414.  
  415. instance.SerializeValue(obj);
  416.  
  417. return instance.builder.ToString();
  418. }
  419.  
  420. void SerializeValue(object value) {
  421. IList asList;
  422. IDictionary asDict;
  423. string asStr;
  424.  
  425. if (value == null) {
  426. builder.Append("null");
  427. } else if ((asStr = value as string) != null) {
  428. SerializeString(asStr);
  429. } else if (value is bool) {
  430. builder.Append((bool) value ? "true" : "false");
  431. } else if ((asList = value as IList) != null) {
  432. SerializeArray(asList);
  433. } else if ((asDict = value as IDictionary) != null) {
  434. SerializeObject(asDict);
  435. } else if (value is char) {
  436. SerializeString(new string((char) value, 1));
  437. } else {
  438. SerializeOther(value);
  439. }
  440. }
  441.  
  442. void SerializeObject(IDictionary obj) {
  443. bool first = true;
  444.  
  445. builder.Append('{');
  446.  
  447. foreach (object e in obj.Keys) {
  448. if (!first) {
  449. builder.Append(',');
  450. }
  451.  
  452. SerializeString(e.ToString());
  453. builder.Append(':');
  454.  
  455. SerializeValue(obj[e]);
  456.  
  457. first = false;
  458. }
  459.  
  460. builder.Append('}');
  461. }
  462.  
  463. void SerializeArray(IList anArray) {
  464. builder.Append('[');
  465.  
  466. bool first = true;
  467.  
  468. foreach (object obj in anArray) {
  469. if (!first) {
  470. builder.Append(',');
  471. }
  472.  
  473. SerializeValue(obj);
  474.  
  475. first = false;
  476. }
  477.  
  478. builder.Append(']');
  479. }
  480.  
  481. void SerializeString(string str) {
  482. builder.Append('\"');
  483.  
  484. char[] charArray = str.ToCharArray();
  485. foreach (var c in charArray) {
  486. switch (c) {
  487. case '"':
  488. builder.Append("\\\"");
  489. break;
  490. case '\\':
  491. builder.Append("\\\\");
  492. break;
  493. case '\b':
  494. builder.Append("\\b");
  495. break;
  496. case '\f':
  497. builder.Append("\\f");
  498. break;
  499. case '\n':
  500. builder.Append("\\n");
  501. break;
  502. case '\r':
  503. builder.Append("\\r");
  504. break;
  505. case '\t':
  506. builder.Append("\\t");
  507. break;
  508. default:
  509. int codepoint = Convert.ToInt32(c);
  510. if ((codepoint >= 32) && (codepoint <= 126)) {
  511. builder.Append(c);
  512. } else {
  513. builder.Append("\\u");
  514. builder.Append(codepoint.ToString("x4"));
  515. }
  516. break;
  517. }
  518. }
  519.  
  520. builder.Append('\"');
  521. }
  522.  
  523. void SerializeOther(object value) {
  524. // NOTE: decimals lose precision during serialization.
  525. // They always have, I'm just letting you know.
  526. // Previously floats and doubles lost precision too.
  527. if (value is float) {
  528. builder.Append(((float) value).ToString("R"));
  529. } else if (value is int
  530. || value is uint
  531. || value is long
  532. || value is sbyte
  533. || value is byte
  534. || value is short
  535. || value is ushort
  536. || value is ulong) {
  537. builder.Append(value);
  538. } else if (value is double
  539. || value is decimal) {
  540. builder.Append(Convert.ToDouble(value).ToString("R"));
  541. } else {
  542. SerializeString(value.ToString());
  543. }
  544. }
  545. }
  546. }
  547. }

Unity3d之MiniJson与LitJson之间的较量的更多相关文章

  1. 关于EnumerateObjectsUsingBlock和for-in之间的较量

      遍历一个数组看谁快 参赛选手 ForLoop, For - in, enumerateObjectsUsingBlock这个三个方法: NSMutableArray *test = [NSMuta ...

  2. Unity3D深入浅出 -组件与节点之间的调用关系

    一.transform组件用途 1.维护场景树 2.对3D物体的平移,缩放,旋转 二.场景树定义 在Hierarchy视图中显示的: 一个game_scene场景,下面有Main Camera节点,D ...

  3. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  4. 如何选择PHP框架?

    PHP是世界上最受欢迎的编程语言之—.最近发布的PHP7令这种服务器的编程语言比以前变得更好,更稳定了. PHP被广泛应用于重大的项目.例如Facebook就是使用PHP来维护和创建它们的内部系统的. ...

  5. 【转】我是如何在SQLServer中处理每天四亿三千万记录的

    原文转自:http://blog.jobbole.com/80395/ 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文 ...

  6. 给swift程序猿留下深刻印象的10个Swift代码

    通过使用单行代码完成同样的 10 个练习,我们来看看 Swift 和其他语言之间的较量. 将数组中每个元素的值乘以 2 使用map来实现 var arr = [1,2,3,4]; var newArr ...

  7. iOS数组使用

    相关链接: ios数组基本用法和排序 NSArray 排序汇总 iOS 数组排序方法 IOS-筛选数组内的元素 关于EnumerateObjectsUsingBlock和for-in之间的较量 [iO ...

  8. 如何在SQLServer中处理每天四亿三千万记录

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  9. (转)SqlServer中处理每天四亿三千万记录的

    项目背景 这是给某数据中心做的一个项目,项目难度之大令人发指,这个项目真正的让我感觉到了,商场如战场,而我只是其中的一个小兵,太多的战术,太多的高层之间的较量,太多的内幕了.具体这个项目的情况,我有空 ...

随机推荐

  1. TCP与UDP在socket编程中的区别 (网络收集转载)

    http://blog.chinaunix.net/uid-26421509-id-3814684.html 一.TCP与UDP的区别 基于连接与无连接  对系统资源的要求(TCP较多,UDP少)  ...

  2. 博弈问题之SG函数博弈小结

    SG函数: 给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移 动者判负.事实上,这个游戏可以认为是所有Impartial Combinatorial Ga ...

  3. jquery 下拉多选插件

    Jquery多选下拉列表插件jquery multiselect功能介绍及使用 Chosen 替代样式表 Bootstrap Chosen

  4. android ListView和GridView拖拽移位实现代码

    关于ListView拖拽移动位置,想必大家并不陌生,比较不错的软件都用到如此功能了.如:搜狐,网易,百度等,但是相比来说还是百度的用户体验较好,不偏心了,下面看几个示例:             首先 ...

  5. ASP.NET - List<> 绑定 DropDownList

    代码: //声明泛型 List<category> inof = new List<category>();//二级分类 //声明类使用的对象类 public class ca ...

  6. 报错消息写在AT SELECTION-SCREEN OUTPUT和START-OF-SELECTION事件下的区别

    今天面试没答上来的问题,其实我是知道的,以前也遇到过.... START-OF-SELECTION下的话会在左下角报错 AT SELECTION-SCREEN OUTPUT消息会弹出框,然后点击就没有 ...

  7. .Net 4.0特性 Tuple元组

    Tuple 字面意思:元组.是.net4.0增加的新特性,是干什么的呢?总结一句,个人觉得这个东西 就是用来在有返回很多种类型的值时可以用到.它提供了8种类型的Tuple,直接看最复杂的那种(其实不是 ...

  8. ajax后台处理返回json值

    public ActionForward xsearch(ActionMapping mapping, ActionForm form, HttpServletRequest request, Htt ...

  9. javascript(七)document.write

    <h1>test</h1> <button type="button" onclick="my_function">点击me ...

  10. qt新进程工作目录的设置(工作目录确实是被子进程继承的,但也可以设置)

    经过试验,qt启动一个新的进程时,这个进程的工作目录是继承父进程的,无论是通过start还是startDetached来启动. 其实对于linux系统,qt底层应该也是调用fork.exec之类的函数 ...