2012-06-30 2 views
0

현재 진행중인 iOS 앱에서 앱이 페이지를 변경할 때마다 정보를 검색하기 위해 데이터베이스에 도달합니다. 쿼리가 실행될 때까지 기다리고 쿼리의 정보가 페이지의 필드를 채우는 동안 팝업, 애니메이션 및로드라는 뷰가 있어야합니다. 원래 인터넷 연결이 있는지 확인하는 방법이 있었고, 팝업이 표시되면 다른 방법으로 쿼리가 실행됩니다. 여기서 이들은 그러나 너무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]; 
    } 

내가는 하위 뷰를 추가 할 말해 사촌 단 한 번 실행하는 나에게 의미가 있지만, 그것을 추가 한 후 나타나지 않는 도대체 왜? 나는 정직하게 아직 프로그래밍에 능숙하지 못하며, 여기에서 진행되고있는 일에 대해 매우 혼란 스럽습니다. 누군가가 여기에서 어떤 빛을 비추는 것을 도울 수 있고, 멋진 일이 될 장면의 올바른 방향으로 나를 지적 할 수 있다면.

여기 백그라운드 스레드로 첫 번째 방법을 시도하고 로그 메시지를 게시 할 때 당신이 얻을 수있는 경우 충돌이 충돌

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 
+0

백그라운드 스레드로 첫 번째 방법을 시도하고 충돌이 발생하면 로그 메시지를 게시하십시오. 또한, 귀하의 subview 루프 접근 방식이 너무 복잡합니다. 다른 모든 항목 위에 표시해야 할 항목이 있으면보기 컨트롤러의 하위보기로 추가하거나 더 나은 방법으로 탐색 컨트롤러의보기로 추가하십시오. – CodaFi

+0

안녕하세요, 답장을 보내 주셔서 감사합니다! 나는 네비게이션 컨트롤러의 견해를 추가 했으므로 좀 더 간단하다. 나는 충돌을 다시 일어나기 위해 일하고있다. 그러나 지금까지는 그렇게하지 않았다. 또한 모든 쿼리에 "performSelectorInBackground"를 추가했습니다. 나는 크래시를 얻으려고 계속 노력할 것이고 오류 로그를 게시 할 것입니다. 그러나 그 변화가 그것을 고칠 수 있었을 것이라고 생각합니까? –

+0

예. 나는 당신의 루프가 통제 불능 상태에 빠졌다고 내기 할 것입니다 (당신은 콜 브레이크를하지 않았습니다). 나는 이것을 당신을위한 대답으로 올려 놓을 것이다.추락하면 내게로 돌아 가라. – CodaFi

답변

0

에서 오류 로그입니다. 내 직감은 당신의 while 회 돌이가 실제로는 break;을 결코 호출하지 않기 때문에 파란색으로 회전하고 있다는 것입니다. 또한, 귀하의 subview 루프 접근 방식이 너무 복잡합니다. 다른 모든 항목 위에 표시해야 할 항목이 있으면보기 컨트롤러의 하위보기로 추가하거나 더 나은 방법으로 탐색 컨트롤러의보기로 추가하십시오.

+0

글쎄 무슨 일이 있었는지 전혀 알지 못하지만 오늘 앱의 다른 부분에서 일하고있을 때 갑자기 80 % 가량의 페이지가 변경되는 것으로 나타났습니다. 나는 어제에서 무엇이 바뀌 었는지 전혀 모르겠다. 나는 나와 함께 일하는 다른 남자가있다. 그리고 그는 그가 어떤 충돌도 아직 경험하지 않았다라고 말한다. 그래서 우리는 꽤 혼란 스럽다. .. 나는 나의 원래 지위에 에러 로그를 추가하고있다. –

+0

어이, 놀라움과 재촉에 대해 유감스럽게 생각합니다. 어제 나는 그것이 필요하다고 생각하지 않았고 내가 잊었던 하나의 루프를 제거했다. 나는 그것을 다시 넣고 충돌은 멈췄다. deatchnewthreadselector가 때때로 메인이 아닌 다른 스레드에 서브 뷰를 추가하도록 요청한다는 내 이론을 확인할 수 있다면 스택 추적을 보면 궁금 할 것입니다. 시간이 있다면 나에게 설명 할 수 있다고 생각합니까 아니면 쓰레기 수거 선택기가 작동하는지 어떻게 더 잘 이해할 수있는 자원을 나에게 줄 수 있습니까? –

+0

detatfhNewThreadWithSelector는 작업 스레드를 생성하여 주 스레드에서 작업을 처리합니다. 물론 이렇게하면 백그라운드에서 리소스에 액세스하거나 백그라운드에서 주 스레드의 리소스에 액세스 할 위험이 있습니다. 이는 매우 좋지 않습니다. 이것이 대신 그랜드 센트럴 디스패치를 ​​스레딩에 사용하는 이유입니다. – CodaFi