2011-11-04 3 views
1

개발중인 응용 프로그램에서 테이블 가로 정렬로 사용되는 가로가 UIScrollView입니다.GCD를 사용하여 UIView 추가

서브 뷰를 추가하면 메인 스레드가 차단되므로 대신 GCD를 사용하고 백그라운드 스레드에서 뷰를 생성하여 메인 큐의 UIScrollView 인스턴스에 추가하기로 결정했습니다.

관련 코드는 이것이다 :

NSUInteger numberOfItems = [_dataSource numberOfItemsInBandView:self]; 
CGFloat __block nextX = 0.0; 

dispatch_queue_t bgQueue = dispatch_queue_create("bandview", NULL); 

for (NSUInteger i = 0; i < numberOfItems; i++) { 
    dispatch_async(bgQueue, ^{ 
     UIView *itemView = [_dataSource bandView:self viewForItemAtIndex:i]; 
     itemView.frame = CGRectMake(nextX, 0, itemView.frame.size.width, itemView.frame.size.height); 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [_scrollView addSubview:itemView]; 
      _scrollView.contentSize = CGSizeMake(nextX, self.frame.size.height); 
     }); 
     nextX += itemView.frame.size.width; 
    }); 
} 

dispatch_release(bgQueue); 

_scrollViewUIScrollView 예를 (제대로 초기화)입니다.

내가 예상 한 것은 서브 뷰가 하나씩 하나씩 UIScrollView에 추가되는 것을 보는 것이지만 대신에 모든 것이 비동기 적으로 실행된다는 것입니다. 그런 다음 스크롤바는 한번에 추가 된 모든 하위 뷰로 새로 고칩니다. 내가 기대하는 것이 아닙니다.)

누구나 내가 여기에서 빠진 것을 발견 할 수 있습니까?

+0

나는 당신이하고있는 일이 괜찮으며 뷰가 생성되어 스크롤 뷰에 매우 빠르게 추가되었다고 생각한다. 지연을 지정할 수있는 경우 dispatch_after를 사용하여 발송물을 main으로 래핑하는 테스트를 수행 할 수 있습니다. 또한 다른 사람들이 제안하는 것처럼 백그라운드 대기열에 대해 동시 대기열을 사용하고 싶을 수도 있습니다. – timthetoolman

답변

3

UI 주 스레드에서 변경해야합니다. 배경 스레드 (async gcd 대기열)에서 UI 변경을 수행하면 표시되는 것처럼 정의되지 않은/바람직하지 않은 동작이 발생합니다. 하위보기를 추가하는 것이 문제의 주요 원인이라고보기는 어렵습니다. 문제는 데이터가 하위 뷰에 대해 검색되는 방식에있을 것입니다. 해결 방법은 모든 하위 뷰를 추가 한 다음 비동기 적으로 데이터를 검색 한 다음 작업이 완료되면 업데이트합니다. 또한 사용자에게 표시되지 않는보기를 추가하지 말고 사용자가 UITableView의 작동 방식과 유사하게 스크롤 할 때 동적으로 추가하십시오.

+0

'dispatch_get_main_queue'가 주 스레드에서 실행되었다고 생각했습니다. 그렇지 않은가요? 나는 그것을 확인하기 위해 NSAssert를 추가했는데 실패하지는 않았다 ... – pgb

+0

아, 나는 그들이 메인 스레드에서 다시 추가되고 있음을 본다. 그러나 모든 것이나 많은 수의 뷰가 대기열에 들어가게 될 가능성이있다. 같은 주 실행 루프 사이클에 들어가고 동시에 왜 동시에 나타나는지에 대해 하나의 효과를 원한다면 애니메이션을 사용하는 것이 좋습니다. – Joe

+0

그게 내가 생각하기에 (동일한 실행 루프 사이클에 큐에 넣는 많은 뷰). 애니메이션 사용은 어떻게됩니까? 'addSubview :'는 "애니메이션 가능"이 아닙니다 ... – pgb

0

또 다른 지적해야 할 점은 UIView 생성 요청을 전달하기 위해 직렬 대기열 (bandview)을 만들었지 만 이는 각 생성 요청이 선형 순서로 발생하고 가능한 가장 동시 적으로 생성된다는 것을 의미합니다 . 원하는 동시 작동이 아닌 경우 글로벌 동시 대기열 중 하나에 작성 요청을 디스패치 할 수 있습니다.

+0

이것은 각 뷰의 너비를 누적해야하기 때문에 의도적 인 것이므로 병렬로 처리 할 수 ​​없습니다. – pgb

관련 문제