1

我正在尝试创建一个登录页面,在尝试时显示等待页面。它UIActivityIndicatorView在主线程上运行,另一个线程在进行连接。当我取消注释时代码工作正常,但当我注释掉NSLog它时它会继续运行。谁能向我解释为什么没有 while 循环时它不存在NSLog?这有点复杂。我有一个控制类来准备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];
  }
4

2 回答 2

0

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

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

于 2013-09-10T05:39:00.367 回答
0

谁能向我解释为什么没有 NSLog 时它不退出 while 循环?

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

当移除NSLog调用时,状态不能改变,因为主线程被阻塞并且运行循环不能处理它的源。

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

于 2013-09-10T07:41:08.110 回答