相关代码:
UIActivityIndicatorView *confirmIndicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[confirmIndicatorView startAnimating];    
NSLog(@"正在登录"); 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         [NSThread sleepForTimeInterval:3];
         [confirmIndicatorView stopAnimating];
          NSLog(@"登录结束");
    });
运行结果:已经打印“登录结束”,但是 UIActivityIndicatorView 动画仍在运行,过了六七秒才结束。
|      1nagato      2015-12-11 04:44:49 +08:00  1 [confirmIndicatorView stopAnimating] 得在主线程执行 | 
|  |      3txx      2015-12-11 06:37:42 +08:00 via iPhone  1 要是 Android 你早就崩出去了...... UI 操作一定要在主线程,哪怕在子线程看起来没问题 | 
|  |      4hohoho      2015-12-11 09:15:06 +08:00 via iPhone 额,这个有多解的。比如用 gcd 的 after ,再比如把你的 stopanimating 放到嵌套的主线程 async 中 | 
|  |      5sagnitude      2015-12-11 09:30:36 +08:00  1 dispatch_get_global_queue 改成 dispatch_get_main_queue() 另外,应该用 NSTimer ,而不是 Thread.sleep 也可以用 performSelector 设定延时 | 
|  |      6altair21      2015-12-11 09:31:52 +08:00 via iPhone  1 ui 更新只能在主线程进行 | 
|      7XcodeUser      2015-12-11 09:37:33 +08:00  1 子线程的 UI 操作不会主动去绘制到屏幕上,只有在 UI 有更新(主线程)或者触摸事件的时候,才会重新绘制的时候, 顺带把子线程的 UI 操作效果展现出来。至于问题的解决方式,如 @hohoho 所说,嵌套一个主线程 operation 就行了 | 
|      8XcodeUser      2015-12-11 09:40:57 +08:00 一句话,子线程是确切的改变的 UI 的属性,但是这些改变不会即时 的绘制到屏幕上。 | 
|  |      9dorentus      2015-12-11 10:09:58 +08:00  1 @UtopiaCHN  只要把 [confirmIndicatorView stopAnimating]; 放在主线程里面,类似这样应该就可以: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [NSThread sleepForTimeInterval:3]; dispatch_async(dispatch_get_main_queue(), ^{ [confirmIndicatorView stopAnimating]; NSLog(@"登录结束"); }); }); | 
|  |      10xjbeta      2015-12-11 13:08:14 +08:00  1 主线程更新 UI | 
|  |      11mornlight      2015-12-11 13:10:41 +08:00 不要在任何子线程上改动 UI 层的东西,你这还好没 crash 。 | 
|  |      12mornlight      2015-12-11 13:21:44 +08:00  1 在 block 里让 thread  sleep 也是不对的。如果你的这个登录操作是 HTTP 请求,应该写到请求的 success block 里而不是强行等待几秒。这个代码是让 block 里的东西延迟 3 秒在主线程执行,没有阻塞效果: ``` dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC),dispatch_get_main_queue(), ^{ //weakify self if need [confirmIndicatorView stopAnimating]; NSLog(@"登录结束"); }); ``` |