在公司一個項目中,用到了highchart做圖表顯示的組件,這就要用到了javascriptcore,代碼就不上了,說說原理。
需求是這樣的,通過http請求server csv格式的數據,然后解析,最后傳入LOCAL的html 中用highchart顯示出來。
由於需要顯示loading,progress等,所以就用了IOS提供的原生NSURLConnection,實現 NSURLConnectionDelegate 和 NSURLConnectionDataDelegate .
原先的設計是這樣的,在controller view實現 <UIWebViewDelegate> ,在viewDidLoad 中加載本地的html文件(這個就是顯示chart的html,里面配置好chart所需要的一切,只等OC傳數據進來),在 - webViewDidFinishLoad: 中初始化JSContext並開始連接請求. 在 - connectionDidFinishLoading: 把數據痛過[JSContext[@"value" callWithArguments:] ]傳給對用的js method。
這樣做,Chart偶爾能出來,更多時候throw exception。exception有兩個,一是: exc_bad_access code=1 address=**** 另一個是: exc_breakpoint (code=exc_i386_bpt subcode=0x0) .
開始懷疑是數據的問題,就把網絡請求到的數據儲存到本地,然后在- webViewDidFinishLoad: 通過JSContext傳給js,結果完全沒有問題,chart每次顯示完美。
通過搜索,在stackoverflow中了解到報錯:exc_bad_access code=1 address=**** 的原因是,使用了已經release的object。通過Debug,跟蹤到出問題時候是在調用js method的時候。因為項目用的是ARC,而我們的服務器是放在AWS上面的,並且注冊的region是Ireland,服務器響應時間一般在2~5s,(比較慢,因為后台需要計算),我想,是不是在等待的這段時間,OC已經把我的JSContext release了,因為我是在 - webViewDidFinishLoad: 中初始化JSContext對象並開始請求數據的,也就是說,JSContext對象至少閑置了2~5s的時間。
開始修改代碼,在 viewdidload 中首先開始請求數據,等請求完成后在開始load local html,然后在- webViewDidFinishLoad: 再初始化JSContext,並把數據傳過去[JSContext[@"value" callWithArguments:] ] ,run ... 一切沒問題。
ARC的確是方便了我們很多,也許我們在享受它帶來好處的同時也要警惕它最大的好處。