2016-02-24 15 views
5

Mam widok kolekcji, w którym używam niestandardowego UICollectionViewFlowLayout. Ten widok kolekcji może ładować obrazy lokalnie lub przez Internet. Jeśli ładuję obrazy lokalnie, każda nawigacja działa dobrze. Jeśli jednak załaduję obrazy przez Internet, ekran ładuje się prawidłowo za pierwszym razem, ale jeśli dotkniesz obrazu i przejdziesz do innego ekranu, a następnie powrócisz z tego ekranu (wszystkie znajdują się w kontrolerze nawigacyjnym), pojawi się Awaria "złego dostępu". Czy ktoś wie, co może być przyczyną.EXC_BAD_ACCESS na [UICollectionView setCollectionViewLayout:]

W viewDidLoad

[self.photosCollectionView registerNib:[UINib nibWithNibName:@"PhotoAlbumPhotosCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:kReuseIdentifierPhotosAlbumPhotosCollectionViewCell]; 

W viewWillAppear

[self fetchImagesFromInternetAsynchronously]; 

self.photosCollectionView.dataSource = self; 
self.photosCollectionView.delegate = self; 

self.photosCollectionViewFlowLayout = [UICollectionViewFlowLayout new]; 
self.photosCollectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; 
self.photosCollectionViewFlowLayout.minimumInteritemSpacing = 2.0f; 
self.photosCollectionViewFlowLayout.minimumLineSpacing = 2.0f; 

CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width; 
CGFloat cellDimension = (screenWidth - 2*self.photosCollectionViewTrailingSpaceConstraint.constant - 3*self.photosCollectionViewFlowLayout.minimumInteritemSpacing)/4 - 1.0; 
CGSize cellSize = CGSizeMake(cellDimension, cellDimension); 
[self.photosCollectionViewFlowLayout setItemSize:cellSize]; 

[self.photosCollectionView setCollectionViewLayout:self.photosCollectionViewFlowLayout]; 

W fetchImagesFromInternetAsynchronously, robię [self.photosCollectionView reloadData] raz obrazy zostały pobrane.

Oto ślad stosu:

stop reason = EXC_BAD_ACCESS (code=1, address=0x8) 
frame #0: 0x0000000112da0e09 UIKit`-[UICollectionViewData layoutAttributesForItemAtIndexPath:] + 248 
frame #1: 0x0000000112d4f2d3 UIKit`-[UICollectionView _setCollectionViewLayout:animated:isInteractive:completion:] + 1893 
frame #2: 0x0000000112d4e86b UIKit`-[UICollectionView setCollectionViewLayout:] + 318 
* frame #3: 0x000000010be6b0aa app`-[PhotoAlbumPhotosPickerViewController viewWillAppear:](self=0x00007fd5830d3e00, _cmd="viewWillAppear:", animated=YES) + 1514 at PhotoAlbumPhotosPickerViewController.m:90 
frame #4: 0x000000010eec85fd UIKit`-[UIViewController _setViewAppearState:isAnimating:] + 710 
frame #5: 0x000000010eec8c98 UIKit`-[UIViewController __viewWillAppear:] + 149 
frame #6: 0x000000010eef8a37 UIKit`-[UINavigationController _startCustomTransition:] + 1203 
frame #7: 0x000000010ef08cdb UIKit`-[UINavigationController _startDeferredTransitionIfNeeded:] + 712 
frame #8: 0x000000010ef09cea UIKit`-[UINavigationController __viewWillLayoutSubviews] + 57 
frame #9: 0x000000010f0afc85 UIKit`-[UILayoutContainerView layoutSubviews] + 248 
frame #10: 0x000000010ede4e40 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 710 
+0

Czy możesz podać więcej kodu na ten temat. Szczególnie, jak radzisz sobie z pobieraniem obrazów z Internetu. \ –

+0

Każde wywołanie do widoku kolekcji musi być wykonane w głównym wątku. – quellish

Odpowiedz

5

Incredible!

To ostatecznie zadziałało. I była nawet podobna awaria, jeśli dodałem widok stopki w widoku kolekcji, który rozwiązał.

Wymień

self.photosCollectionViewFlowLayout = [UICollectionViewFlowLayout new]; 

z

self.photosCollectionViewFlowLayout = (UICollectionViewFlowLayout*)self.photosCollectionView.collectionViewLayout; 

Lub dodaj ten w viewWillDisappear (to jednak nie pozbyć się widoku stopka katastrofie, więc lepiej użyć pierwszego podejścia.

self.photosCollectionView.delegate = nil; 
self.photosCollectionView.dataSource = nil; 
+0

Nie działa dla mnie, aplikacja nie ulega awarii, ale widok kolekcji nie wydaje się zapełniać. Co jeszcze bardziej dziwne jest to, że doświadczam tylko awarii na symulatorze, nie mam problemu z zawieszaniem się z prawdziwym iPhonem. – Supertecnoboff

+0

Twoja linia rozwiązań nic nie robi ... o ile wiem. Warto ponownie zbadać, dlaczego to zadziałało. –

+0

Mogę ci powiedzieć, że samo ustawienie tej linii działa. Usunięto, a nie. – OutOnAWeekend

2

Obiekty UIKit nie są bezpieczne dla wątków, chociaż nie uwzględniono kodu wywołującego to w qu estium, prawdopodobnie fetchImagesFromInternetAsynchronously wykonuje pracę na innym wątku w oparciu o sygnaturę metody. I z tego wątku jest wywoływany [self.photosCollectionView reloadData]. Widok kolekcji powinien być dostępny tylko z głównego wątku:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
    [self.photosCollectionView reloadData]; 
}]; 
+0

Zrobiłem to próba, a także wyglądało to bardziej zrozumiałe. Ale to nie naprawiło błędu. – OutOnAWeekend

Powiązane problemy