如果没有NSLog,while循环不能退出

时间:2013-09-10 04:14:15

标签: ios objective-c nsthread

我正在尝试创建一个登录页面,在尝试时显示等待页面。它在主线程上运行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];
  }

2 个答案:

答案 0 :(得分:0)

你永远不应该使用空循环来在线程之间进行同步,这会浪费大量的CPU时间,更重要的是,你发现你的循环不会退出。因为编译器会优化代码,你永远无法得到[connection isAttamptingWS]的正确结果。

但要解决这个确切的问题(看看为什么会发生这种情况)我认为你可以将 volatile 关键字添加到isAttamptingWS的返回值。

答案 1 :(得分:0)

  

有人可以向我解释为什么没有NSLog时它不会退出while循环吗?

您的代码(隐形)使用主线程的运行循环来处理连接和计时器回调。这些回调控制连接对象的状态,因此控制循环条件。

删除NSLog调用时,状态无法更改,因为主线程被阻止且runloop无法处理其来源。

再次插入呼叫时,NSLog的实现轮询runloop(可能与asl服务器通信)。在对NSLog的调用中,运行循环可以将延迟的操作,计时器或连接回调分派为dbConnectionDidConnected:。在此方法中,循环条件变为false,并且一旦对NSLog的调用返回,循环就会退出。