2016-02-24 18 views
5

Ho una vista di insieme in cui sto usando un custom UICollectionViewFlowLayout. Questa vista di raccolta può caricare immagini localmente o tramite internet. Se carico localmente le immagini, ogni navigazione funziona bene. Se però carico le immagini su Internet, lo schermo si carica correttamente la prima volta ma se si tocca un'immagine e si passa ad un'altra schermata, e poi si torna da quella schermata (sono tutte in un controller di navigazione) c'è un arresto anomalo. Qualcuno sa quale potrebbe essere la ragione.EXC_BAD_ACCESS su [UICollectionView setCollectionViewLayout:]

In viewDidLoad

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

In 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]; 

In fetchImagesFromInternetAsynchronously, faccio un [self.photosCollectionView reloadData] una volta le immagini sono stati recuperati.

Ecco la traccia dello stack:

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

Puoi fornire altro codice per questo. In particolare come gestisci il recupero di immagini da Internet. \ –

+0

Qualsiasi chiamata alla vista raccolta deve essere eseguita sul thread principale. – quellish

risposta

5

Incredibile!

Questo è ciò che alla fine ha funzionato. E c'è stato anche un incidente simile se avessi aggiunto la vista del piè di pagina nella vista della raccolta che questo risolveva.

Sostituire

self.photosCollectionViewFlowLayout = [UICollectionViewFlowLayout new]; 

con

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

Oppure aggiungi questo a viewWillDisappear (questo però non sbarazzarsi del crash vista piè di pagina, in modo da meglio utilizzare il primo approccio.

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

Non funziona per me, l'app non si arresta in modo anomalo, ma la vista raccolta non sembra popolare. Cosa ancora più strana è che sto riscontrando solo il problema del crash sul simulatore, non sto avendo il problema con il vero iPhone. – Supertecnoboff

+0

La tua linea di soluzioni non fa nulla ... per quanto posso dire. Vale la pena di indagare sul perché questo ha funzionato. –

+0

Posso dirti solo mettendo questa linea da sola, ha funzionato. Rimosso, e non lo fece. – OutOnAWeekend

2

Gli oggetti UIKit non sono thread-safe, anche se non hai incluso il codice che lo attiva nel tuo qu estion, è probabile che fetchImagesFromInternetAsynchronously stia eseguendo il lavoro su un altro thread basato sulla firma del metodo. E da quel thread è stato richiamato [self.photosCollectionView reloadData]. La vista raccolta deve essere accessibile solo dal thread principale:

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

Ho dato a questo una prova così come sembrava più comprensibile. Ma questo non ha risolto l'errore. – OutOnAWeekend