我无法复现确切的问题(WebThread: EXC_BAD_ACCESS (code=1, address=0x5)
—摘自你的其他问题),但我注意到WebSocket消息正在缓冲,如果你把应用程序留在后台足够长的时间,可能会导致内存压力问题,这可能是此崩溃的原因。
然而,在研究这个问题的过程中,我确实成功地让应用程序崩溃,并出现了源自WebThread
的EXC_BAD_ACCESS
,所以我会在这里发布详细信息,希望能对您或其他人有所帮助。
为了解决这个问题,我的WebSocket服务器简单地广播当前时间给任何连接的客户端。
正如我之前提到的,当应用程序进入后台时,我注意到UIWebView正在缓冲WebSocket消息。为了防止这种情况发生,我想要在应用程序进入后台时关闭WebSocket连接。
在托管UIWebView的视图控制器中,我为UIApplicationWillResignActiveNotification
注册了一个选择器,并在该选择器中调用了我的Web页面中的一个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.m:
- (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连接传输。