iOS中json解析出現的null,nil,NSNumber的問題

来源:http://www.cnblogs.com/56ik/archive/2016/01/13/5128824.html
-Advertisement-
Play Games

在iOS開發過程中經常需要與伺服器進行數據通訊,Json就是一種常用的高效簡潔的數據格式。問題現象但是幾個項目下來一直遇到一個坑爹的問題,程式在獲取某些數據之後莫名崩潰。其實很早就發現了原因:由於伺服器的資料庫中有些欄位為空,然後以Json形式返回給客戶端時就會出現這樣的數據:?1"somevalu...


在iOS開發過程中經常需要與伺服器進行數據通訊,Json就是一種常用的高效簡潔的數據格式。

問題現象

但是幾個項目下來一直遇到一個坑爹的問題,程式在獲取某些數據之後莫名崩潰。其實很早就發現了原因:由於伺服器的資料庫中有些欄位為空,然後以Json形式返回給客戶端時就會出現這樣的數據:

?
1 "somevalue":null

通過JsonKit 這個第三方庫解析出來的數據就成了

?
1 somevalue = "<null>";

這個數據類型不是nil 也不是 String。 解析成對象之後,如果直接向這個對象發送消息(eg:length,count 等等)就會直接崩潰。提示錯誤為:

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

解決方法

其實一直沒有找到完美的解決辦法,坑了我很久。

1、最開始的解決方法就是為了應付當前遇到的崩潰,看看哪個欄位可能為空,那麼就對該欄位使用前進行判斷,通過崩潰時的錯誤提示可以看出,這樣的欄位解析成的對象是 NSNull 類型的,所以可以直接判斷是不是此類型:

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

因為欄位實在太多,就找一個補一個。

2、後來想徹底解決這問題,就打算從數據源下手,其實應該可以用正則表達式匹配這個null ,然後進行替換,奈何正則是我的硬傷啊。於是就相出了一個山寨方法:字元串匹配。在獲取到伺服器返回的Json時,返回結果時string對象,於是就先替換 null 為 為空字元””,然後再解析。

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

這個方法本來很奏效,但是我這裡的伺服器返回極不簡潔,各種垃圾數據(不吐槽這了)。。。反正這樣會導致json無法解析了。

3、最後沒有辦法,只能在解析的時候下手,把是NSNull 類型的值替換成nil。 一般就寫個tool方法,然後解析時調用。但是嫌太麻煩,就想弄寫個巨集,通過搜索驚奇的發現巨集也是可以有返回值的,結果如下:

?
1 2 3 4 5 6 7 8 #define VerifyValue(value)\ ({id tmp;\ if ([value isKindOfClass:[NSNull class]])\ tmp = nil;\ else\ tmp = value;\ tmp;\ })\

巨集里的最後一句語句便是返回值。然後在解析數據時調用巨集:

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

4、如果你使用AFNetwork 這個庫做網路請求的話,可以用以下代碼,自動幫你去掉這個討厭的空值

?
1 self.removesKeysWithNullValues = YES;

5、終極方案
終於找到了一勞永逸的方案,牛逼的老外寫了一個Category,叫做NullSafe ,在運行時操作,把這個討厭的空值置為nil,而nil是安全的,可以向nil對象發送任何message而不會奔潰。這個category使用起來非常方便,只要加入到了工程中就可以了,你其他的什麼都不用做,對,就是這麼簡單。詳細的請去Github上查看;
https://github.com/nicklockwood/NullSafe

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • eMMC主要是針對手機和平板電腦等產品的內嵌式存儲器,由於其在封裝中集成了一個控制器,且提供標準介面並管理快閃記憶體等優勢,越來越受到Android手機廠商的青睞,以eMMC為存儲設備的android手機,其文件系統(system、data分區)一般採用ext4格式。如小米手機的線刷包:一.img解包 之...
  • GridView(網格視圖)講解一、GridView(網格視圖)這個是控制項也是比較多,和listView的很多地方都是一樣的,但是GridView可以顯示多列,而listView只能顯示一列,個人覺得這是最大的區別。常用屬性:android:columnWidth:設置列的寬度android:gra...
  • 註冊JPush賬號 JPush官網下載SDK下載地址:https://www.jpush.cn根據文檔進行集成文檔:http://docs.jpush.io/guideline/ios_guide/文檔介紹的已經很詳細了註意點:App Key需要登錄,添加自己的應用即可獲得,文檔中沒有給出跳轉的鏈接...
  • 首先申明下,本文為筆者學習《OpenGL ES應用開發實踐指南(Android捲)》的筆記,涉及的代碼均出自原書,如有需要,請到原書指定源碼地址下載。 《Android學習筆記——OpenGL ES的基本用法、繪製流程與著色器編譯》中實現了OpenGL ES的Android版HelloWorld,並...
  • 一,效果圖。二,工程圖。三,代碼。RootViewController.h#import @interface RootViewController : [email protected]#import "RootViewController.h"#im...
  • Xcode中的常用快捷鍵
  • 懶載入又叫延遲載入,他有兩個好處,第一:當使用時才載入,而不是一開始就載入,為CPU節省時間做其他的事情,第二:記載之前會判斷數據是否為空,如果空是空的才去載入,避免了重覆載入數據,系統可能會清理記憶體使數組為空,這樣確保數組不為空 有時plist文件不是一層可能兩層甚至多層,記住先建小模型,究竟如....
  • 管理MySQL資料庫最簡單和最便利的方式是PHP腳本。運行PHP腳本使用HTTP協議和android系統連接。我們以JSON格式編碼數據,因為Android和PHP都有現成的處理JSON函數。下麵示例代碼,根據給定的條件從資料庫讀取數據,轉換為JSON數據。通過HTTP協議傳給android,and...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...