2016-07-19 11 views
1

Swift 2.2와 Realm 1.0.2를 사용하여 iOS 8.0 이상을 타겟팅하는 앱을 데이터 저장소로 개발하고 있습니다.viewWillTransitionToSize에서 오류가 발생했습니다.

나는 충돌 로그에이 코드와 관련된 충돌을 많이보고 있어요 것은 나는 현재 그들에게 자신을 재현 할 수 있지만이 코드에서 셀을 표시하는 UICollectionView을 포함하는 뷰 컨트롤러에 나타납니다

/// Resize cells when orientation changes. 
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { 
    if visible { 
     dispatch_async(dispatch_get_main_queue()) { 
      if let coordinator = coordinator as UIViewControllerTransitionCoordinator? { 
       if self.collectionView != nil { 
        self.collectionView.reloadData() 

        coordinator.animateAlongsideTransition({ context in 
         self.collectionView.performBatchUpdates(nil, completion: nil) 
        }, completion: nil) 
       } 
      } 
     } 
    } 
} 

을 방향에 따라 크기가 다릅니다. 왜 내가 애니메이션 앞에 self.collectionView.reloadData()이 필요한지 명확하지 않지만 여백이 없으면 의도 한 것보다 훨씬 넓습니다.

0 libobjc.A.dylib     0x0000000180f400b0 objc_retain + 16 (objc-object.h:341) 
1 UIKit       0x00000001873a1570 -[_UIViewControllerTransitionCoordinator _animateAlongsideTransitionInView:systemCompletion:animation:completion:] + 112 (UIViewControllerTransitioning.m:865) 
2 UIKit       0x0000000186b17f40 -[_UIViewControllerTransitionCoordinator animateAlongsideTransition:completion:] + 68 (UIViewControllerTransitioning.m:906) 
3 MyApp       0x00000001000fc78c 0x1000c0000 + 247692 
4 libdispatch.dylib    0x000000018130d4bc _dispatch_call_block_and_release + 24 (init.c:760) 
5 libdispatch.dylib    0x000000018130d47c _dispatch_client_callout + 16 (object.m:506) 
6 libdispatch.dylib    0x0000000181312b84 _dispatch_main_queue_callback_4CF + 1844 (inline_internal.h:1063) 
7 CoreFoundation     0x0000000181878d50 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 (CFRunLoop.c:1613) 
8 CoreFoundation     0x0000000181876bb8 __CFRunLoopRun + 1628 (CFRunLoop.c:2718) 
9 CoreFoundation     0x00000001817a0c50 CFRunLoopRunSpecific + 384 (CFRunLoop.c:2814) 
10 GraphicsServices    0x0000000183088088 GSEventRunModal + 180 (GSEvent.c:2245) 
11 UIKit       0x0000000186a82088 UIApplicationMain + 204 (UIApplication.m:3772) 
12 MyApp       0x00000001000c92d8 0x1000c0000 + 37592 
13 libdyld.dylib     0x000000018133e8b8 start + 4 (start_glue.s:78) 

내가 다른 화면에서 방향을 변경 한 후 신속하게 UICollectionView와 하나에 돌아 오는하여 유사한 사고를 유발 할 수 있도록 사용

는 여기에 내가 얻을 추적합니다. if visible 수표가 문제를 해결하는 것으로 보입니다.이 충돌이 훨씬 적어 지지만 일부는 여전히 줄어 듭니다. 이러한 흔적을 읽으면서 내 코드 또는 리소스에서 문제를 찾아야하는 모든 아이디어는 크게 감사 할 것입니다.

+2

메인 스레드에 블록을 넣을 GCD 호출이있는 이유는 무엇입니까? 나는'viewWillTransitionToSize' (다른 UIKit 메소드와 마찬가지로)가 메인 스레드에서 호출 될 것이라고 믿는다. 그게 네 추락 사고의 원인이 될지 모르겠다. – dylansturg

+0

@DylanS 그 문제를 찾은 제안 때문에 제안서가 있기 때문에 거기에 불필요한 것들이 몇 가지있을 것입니다. 내 이해는 그것이 이미 메인 스레드에 있다면,'dispatch_async'는 단지 중복되지만 상처를주지 않는다는 것입니다. –

+1

사실 일 수도 있고 아닐 수도 있습니다. Apple이'viewWillTransitionToSize'를 구현했다면 반환하면'coordinator '에 대한 수정이 무효하거나 불안정해질 것입니다. 코드가 GCD로 보내지는 블럭에 싸여 있기 때문에 블럭이 실행되기 전에'viewWillTransitionToSize'가 리턴 될 것입니다 (때로 GCD는 주어진 큐에서 실행될 것이라고 약속하지만 순서에 관한 약속은 아닙니다). 예를 들어,보기 컨트롤러가 애니메이션을 시작하면 GCD가 블록을 실행합니다 ... 중간에 애니메이션을 추가 받으면 어떻게 반응합니까? 그것은 정의되지 않을 수도 있습니다. – dylansturg

답변

3

몇 가지 작은 문제가 여기에 있습니다 :

  • 항상
  • GCD 호출이 예상치 못한 불일치

가 발생할 수 있습니다 UIViewController에 라이프 사이클 방법에 super를 호출 dispatch_async에만 일정 코드 것을 명심하십시오 GCD로 차단하고 실행시기에 대한 어떠한 보증도하지 않습니다. 애니메이션이 시작된 후에 해당 블록이 실행되어 크기가 일관성없는 상태로 남을 수 있습니다.