2013-07-05 1 views
3

내 iPhone 앱에서 tableView : cellForRowAtIndexPath : 백그라운드 스레드에서 호출되는 경우가 종종 발생합니다.왜 tableView가 : cellForRowAtIndexPath : 백그라운드 스레드에서 호출되고 있습니까?

분명히, 이것은 일어나지 않아야합니다. 나는 문제의 스레드에 대한 스택에서 볼 수있는 유일한 것은 충돌이 WebTryThreadLock에서 발생

 
-_WebTryThreadLock(bool) 
-_dequeuReusableViewOfType 
-tableView:cellForRowAtIndexPath: 
-_createPreparedCellForGlobalRow:withIndexPath 
-_pthread_qathread 

입니다 - - 내 객체가 jQuery과에 위임하고 기초가 호출되고, 그것을 호출 아니에요 없음 정말 놀랍지 만 스레드 세이프가 아니기 때문에 메인 스레드에서 호출해서는 안됩니다.

하지만 내 tableView 대리인이 백그라운드 스레드에서 호출되는 이유는 무엇입니까?

나는 배경 스레드에서 [tableView reloadData]를 호출하면 그렇게 할까?

필자는 항상 주 스레드에 상관없이 호출을 전달할 것이라고 생각했습니다. 나는 그 일을 잘하고 있는지 확신 할 수는 없지만 나는 그것을 점검 할 것이다. 그러나 실제로, UIKit이이를 확인하고 주 스레드에서 대리자 메서드를 호출해서는 안된다.

+0

자세한 충돌 로그를 게시 할 수 있습니까? 또한 타사 프레임 워크를 포함하고 있습니까? –

+1

당신은 "UIKit이 그걸 확인해서는 안되니?"라고 묻습니다. 나는 당신이 왜 그것을 묻는 지 이해할 수있다. 그러나 단순한 사실은 그렇지 않다는 것이며, 단순히 테이블 뷰 관련 호출이 메인 큐에서 수행되는지를 확인해야한다는 것이다. – Rob

+0

코드를 게시하고 더 나은 답변을 얻으려면 로그를 닫으십시오. – Jatin

답변

3

보조 스레드에서 [tableView reloadData]으로 전화를 걸 수 없습니다. 보조 스레드에서 UIKit 항목을 호출 할 수 없습니다 (예외는 몇 가지 예 : UIImage). 여기에는 직선 게터와 세터를 포함한 모든 tableView 메소드가 포함됩니다. 렌더링과 관련이 있는지 여부는 중요하지 않습니다.

+0

그 점도 저의 이해였습니다. 확인해 주셔서 감사합니다. 신중하게 코드를 확인한 후에, 나는 그렇게하지 않을 것이라고 확신합니다. 그러나 나는 트리플 체크를 트리플 체크 할 것이다. 따라서, bg 스레드에서 cellForRowAtIndexPath를 호출하는 기초를 초래할 수있는 (다른) 시나리오를 생각해 볼 수 있습니까? – Jordan

+2

@Jordan 테이블 뷰에는 4 가지 다른 'reload ...'메소드가 있으므로 백그라운드 스레드에서 호출하지 않도록주의하십시오. 또한'scrollTo ... '메소드. 또한 테이블 뷰의 프레임을 변경하거나, 예를 들어 푸시 한 뷰 컨트롤러를 터뜨리는 등의 호출을하지 마십시오. 이는 모두 UIKit 작업이므로 UIKit 호출을 모두 메인 대기열, 괜찮을거야. – Rob

+1

"그래서 메인 큐에서 모든 UIKit 호출을 수행하면 괜찮을 것입니다."- 예, 그렇습니다. 그것이 내가 생각한 것입니다. 이 코드를 어딘가에 가지고있을 것 같지만 아직 찾지 못했습니다! – Jordan

2

당신의 뷰 컨트롤러 주위에이 중 일부를 뿌린다 흥미로운 일이 될 수 있습니다 (! [NSThread isMainThread])

경우 { NSLog (@ "응?"); }

UIKit/IOS는 백그라운드 스레드에서 테이블 뷰 대리자 메서드를 호출하기 위해 자체적으로 결정하지 않을 것이라고 확신합니다. dispatch_async, detachNewThreadSelector, performSelectorInBackground가 있습니까?

+0

> UIKit/IOS는 백그라운드 스레드에서 테이블 뷰 대리자 메서드를 호출하는 것이 자신의 것으로 결정하지 않을 것이라고 확신합니다. 그렇습니다. 그것은 내 믿음 이었지만, 지금까지는 달리 믿을만한 이유가 없습니다. – Jordan

+0

내가 할 수있는 모든 곳에서 isMainThread를 검사하고, 잘못된 스레드에있는 곳에서 스택 덤프를하고, 처음에 어떻게 거기에 도착했는지를 알기를 바랍니다. – Jordan

+0

+1 용 .... 응? –