我無法複製確切的問題(WebThread: EXC_BAD_ACCESS (code=1, address=0x5)
- 從您的other question中獲取),但我確實注意到WebSocket消息正在被緩衝,所以如果您將應用程序保留在背景中足夠長的時間,遇到可能導致此次事故的內存壓力問題。
然而,在研究這個問題的過程中,我還是設法使應用程序可靠地從WebThread
一個EXC_BAD_ACCESS
發起崩潰,所以我會在這裏發表的細節,希望它可能使用到您或他人。
就這個問題而言,我的WebSocket服務器只是每秒向任何連接的客戶端廣播時間。
正如我所提到的,我注意到當應用程序背景時UIWebView正在緩衝WebSocket消息。爲了防止這種情況發生,我想在應用程序移入後臺時關閉WebSocket連接。
在我主持的UIWebView的視圖控制器,我註冊了一個選擇爲UIApplicationWillResignActiveNotification
並在這選擇,我打電話給我的網頁中的JavaScript函數,WebSocket的對象上調用close
。
ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
}
- (void)appWillResignActive:(NSNotification *)notification
{
[self.webView stringByEvaluatingJavaScriptFromString:@"closeWebSocket();"];
}
網頁:
function closeWebSocket() {
socket.close(); // socket is an instance of WebSocket
socket = undefined;
}
我想WebSocket的重新連接,當應用程序被移回前臺,所以我註冊了另一種選擇,這次是UIApplicationDidBecomeActiveNotification
,並在該選擇器中調用另一個函數來初始化WebSocket連接。
ViewController。L:
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)appWillResignActive:(NSNotification *)notification
{
[self.webView stringByEvaluatingJavaScriptFromString:@"closeWebSocket();"];
}
- (void)appDidBecomeActive:(NSNotification *)notification
{
[self.webView stringByEvaluatingJavaScriptFromString:@"openWebSocket();"];
}
網頁:
function openWebSocket() {
socket = new WebSocket("ws://" + document.location.host + "/ping");
socket.onopen = function() { console.log("Opened"); };
socket.onmessage = function (message) {
var log = $('#log');
log.html(message.data + '<br>' + log.html());
console.log(message.data);
};
socket.onclose = function() { console.log("Closed"); };
}
運行應用程序時,WebSocket連接建立,收到的消息,以及應用程序移動到後臺。幾秒鐘後,我將應用程序帶回前臺(通過點擊應用程序圖標),應用程序崩潰,類似於WebThread: EXC_BAD_ACCESS (code=1, address=0x5
的異常。造成這種情況的原因是當應用程序被帶回到前臺時,對openWebSocket()
的JavaScript調用的評估。延遲執行openWebSocket()
幾毫秒解決了問題。通過appDidBecomeActive
方法結束這樣看:
- (void)appDidBecomeActive:(NSNotification *)notification
{
[self.webView stringByEvaluatingJavaScriptFromString:@"setTimeout(openWebSocket, 5);"];
}
再次運行應用程序時,WebSocket連接建立,接收到的消息,和應用程序背景執行。幾秒鐘後,當我將應用程序帶回前臺時,應用程序沒有崩潰,並且消息通過WebSocket連接再次開始。
你是否在自定義NSUrlProtocol?並在你的webView控制器中做一些像registerClass的事情?發佈您的崩潰日誌或網頁瀏覽代碼。 – johnMa
你能找到你的應用崩潰的原因嗎? – sunkehappy
顯示崩潰的堆棧跟蹤。 –