iOS加载动画无法正确显示

时间:2012-06-30 20:04:06

标签: ios loading nsthread

在我正在处理的iOS应用程序中,应用程序会在每次页面更改时命中数据库以检索信息。在等待查询执行以及查询中的信息填充页面上的字段时,应该是弹出,动画和加载的视图。最初有一个方法检查是否有互联网连接,如果有显示弹出窗口,然后另一个方法将执行查询。这些线程如此

[NSThread detachNewThreadSelector:@selector(appStartedLoading) toTarget:self withObject:nil]; 

然而,这导致了大约10%的崩溃问题。我并不完全理解这个问题,但我认为这是因为分离这样的新线程有时(并不总是)会导致从不是主线程的线程添加子视图。这是一个子问题,我的理论是否符合逻辑。

无论哪种方式,我们都摆脱了那种做事方法,只是一次调用一个方法而没有线程化。喜欢这个

[self appStartedLoading];
[self performQuery]; //fake placeholder method for examples sake.

但这导致加载屏幕显示在下一页已经显示并且查询已经执行之后,可能是因为应用程序太忙于查询。我尝试在子视图中使用的方式在单独的线程中运行查询,但它没有更改它。我已经尝试在主线程上运行appStartedLoading方法并告诉它阻塞,即

[self performSelectorOnMainThread:@selector(appStartedLoading) withObject:nil waitUntilFinished: YES]; 

我认为,因为它被告知要阻止它不会执行查询,直到添加子视图和动画然后它仍然首先更改页面然后显示加载屏幕。我也尝试在方法中加入小循环,直到子视图被添加才完成,但即使子视图没有显示在屏幕上,它们也会立即完成。循环是这样的。

while([[[self.window.subviews objectAtIndex:0] subviews] indexOfObject:loaderView] == NSNotFound)
    {
        i++;
        NSLog(@"this %d", i);
        [[self.window.subviews objectAtIndex:0] addSubview:loaderView];
    }  

对我来说有意义的是,只执行一次cuz我告诉它添加子视图,但为什么添加它后它不会出现?我真的不擅长编程而且非常混淆这里正在发生的事情,如果有人可以帮助在这里提供一些亮点并指出我正在幕后发生的事情的正确方向,那将是非常棒的。

这是来自崩溃的错误日志

 bool _WebTryThreadLock(bool), 0xc8a7fa0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
1   WebThreadLock
2   -[UITextView setFrame:]
3   UIViewCommonInitWithFrame
4   -[UIView initWithCoder:]
5   -[UIScrollView initWithCoder:]
6   -[UITextView initWithCoder:]
7   UINibDecoderDecodeObjectForValue
8   -[UINibDecoder decodeObjectForKey:]
9   -[UIRuntimeConnection initWithCoder:]
10  UINibDecoderDecodeObjectForValue
11  UINibDecoderDecodeObjectForValue
12  -[UINibDecoder decodeObjectForKey:]
13  -[UINib instantiateWithOwner:options:]
14  -[UIViewController _loadViewFromNibNamed:bundle:]
15  -[UIViewController loadView]
16  -[UIViewController view]
17  -[UIViewController contentScrollView]
18  -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:]
19  -[UINavigationController _layoutViewController:]
20  -[UINavigationController _startTransition:fromViewController:toViewController:]
21  -[UINavigationController _startDeferredTransitionIfNeeded]
22  -[UINavigationController __viewWillLayoutSubviews]
23  -[UILayoutContainerView layoutSubviews]
24  -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
25  -[NSObject performSelector:withObject:]
26  -[CALayer layoutSublayers]
27  CA::Layer::layout_if_needed(CA::Transaction*)
28  CA::Context::commit_transaction(CA::Transaction*)
29  CA::Transaction::commit()
30  CA::Transaction::release_thread(void*) 
31  _pthread_tsd_cleanup

1 个答案:

答案 0 :(得分:0)

尝试使用后台线程的第一种方式,并在您可以使其崩溃时发布日志消息。我的预感是你的while循环正在旋转到蓝色,因为你从来没有真正在那个东西上调用break;。此外,您的子视图循环方法太复杂了。如果您需要在其他所有内容上显示某些内容,请将其添加为视图控制器的子视图,或者更好的是,它是导航控制器的视图。