我正在尝试创建一个登录页面,在尝试时显示等待页面。它在主线程上运行UIActivityIndicatorView
,在另一个线程上运行连接。我取消注释NSLog
时代码工作正常,但是当我将其注释掉时它仍然保持运行。任何人都可以向我解释为什么在没有NSLog
时它不存在while循环?这有点复杂。我有一个控制类,用于准备websocket
命令,当且仅当websocket
成功连接时才会触发它。
行动流程如下:
点击 LoginButton
- > rootView
来电[_spinner startAnimating];
- >尝试连接websocket
- >成功连接后发送登录命令。
rootView
必须为微调器设置动画并等待响应。
[_spinner startAnimating];
[NSThread detachNewThreadSelector:@selector(attampingWS) toTarget:self withObject:nil];
- (void) attampingWS {
while ([connection isAttamptingWS] && ![connection isConnectedToWebSocket]) {
/** waiting until it's done **/
// NSLog(@"?");
}
if ([connection isConnectedToWebSocket]) {
[self proceedLogin];
[_spinner performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:NO];
}
}
连接类中的:
@property(nonatomic) NSTimer *attampConnectionTimeOut;
@property(nonatomic) NSTimer *attampConnection;
@property BOOL isConnectedToWebSocket;
- (BOOL) isAttamptingWS {
return [_attampConnection isValid];
}
- (BOOL) isWaitingForResponse {
return [_waitingForResponse isValid];
}
/** this method is redirected from websocket by using delegation **/
- (void)dbConnectionDidConnected:(websocket *)connection {
[self _terminateAttamptingConnection];
[self setIsConnectedToWebSocket:TRUE];
}
答案 0 :(得分:0)
你永远不应该使用空循环来在线程之间进行同步,这会浪费大量的CPU时间,更重要的是,你发现你的循环不会退出。因为编译器会优化代码,你永远无法得到[connection isAttamptingWS]的正确结果。
但要解决这个确切的问题(看看为什么会发生这种情况)我认为你可以将 volatile 关键字添加到isAttamptingWS的返回值。
答案 1 :(得分:0)
有人可以向我解释为什么没有NSLog时它不会退出while循环吗?
您的代码(隐形)使用主线程的运行循环来处理连接和计时器回调。这些回调控制连接对象的状态,因此控制循环条件。
删除NSLog
调用时,状态无法更改,因为主线程被阻止且runloop无法处理其来源。
再次插入呼叫时,NSLog的实现轮询runloop(可能与asl服务器通信)。在对NSLog
的调用中,运行循环可以将延迟的操作,计时器或连接回调分派为dbConnectionDidConnected:
。在此方法中,循环条件变为false,并且一旦对NSLog
的调用返回,循环就会退出。