In the iOS app I am currently working on, the app hits a database to retrieve information every time the page changes. While waiting for the query to execute and the information from the query to populate the fields on the page there is supposed to be a view that popups, animates and says loading. Originally there was a method that checked if there was an internet connection, and if there was would display the popup and then another method would execute the query. These where threaded like so
[NSThread detachNewThreadSelector:@selector(appStartedLoading) toTarget:self withObject:nil];
However this lead to a crash problem about 10% of the time. I don't entirely understand that problem, but I think it was because detaching a new thread like that would sometimes (not always) cause a subview to be added from a thread that's not the main thread. that's kind of a sub question here, wether my theory is logical or not.
Either way we got rid of that method of doing things and just called the methods one at a time without threading. Like this
[self appStartedLoading];
[self performQuery]; //fake placeholder method for examples sake.
But this caused the loading screen to show up after the next page was already display and the query was already executed, presumably because the app was too busy with the query. I've tried running the query in a separate thread the way the subview used to but it did not change it. I've tried running the appStartedLoading method on the main thread and telling it block i.e.
[self performSelectorOnMainThread:@selector(appStartedLoading) withObject:nil waitUntilFinished: YES];
I would think that because it is told to block it wouldn't perform the query till after the subview is added and animating then but it still changes pages first and then displays the loading screen. I've also tried putting little loops in the method to make it not finish till the subview has been added but they finish right away even though the subview does not show up on the screen. The loop is this.
while([[[self.window.subviews objectAtIndex:0] subviews] indexOfObject:loaderView] == NSNotFound)
{
i++;
NSLog(@"this %d", i);
[[self.window.subviews objectAtIndex:0] addSubview:loaderView];
}
It makes sense to me that in only executes once cuz I tell it to add the subview, but why the heck isn't it appearing after adding it? I'm not honestly good at programming yet and very confused by what's going on here, if someone could help shed some light here and point me in the right direction of what's going on behind the scenes that'd be awesome.
here's the error log from crashes
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