2015-04-30 12 views
5

Ứng dụng của chúng tôi có UICollectionView và từ điển dataSource được cập nhật thường xuyên. Chúng tôi không bao giờ biết khi nào cập nhật tiếp theo sẽ xảy ra. Phương thức tải lại Xem bộ sưu tập có thể được gọi sau khi người dùng nhấn vào nút hoặc có thể xảy ra không đồng bộ sau khi yêu cầu mạng thành công. Với thông tin trên, chúng tôi có nguy cơ có điều kiện chủng tộc trong khi tải lại chế độ xem bộ sưu tập và cập nhật nguồn dữ liệu của nó cùng một lúc. Chúng tôi thậm chí đã đăng ký vụ tai nạn sau và chúng tôi tin rằng điều đó đã xảy ra do điều kiện chủng tộc được mô tả ở trên. Thông báo sự cố:Ngăn ngừa sự cố trong UICollectionView

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]' 

Phương pháp gây ra sự cố: collectionViewLayout sizeForItemAtIndexPath:.

Phương pháp này tính toán chiều cao cho phần của bộ sưu tập Chế độ xem tùy thuộc vào các mục được tính trong số sectionWithProducts. Số lỗi này bị lỗi vì số lượng dataSource nhỏ hơn indexPath.row. Và dòng gây ra tai nạn:

NSArray *sectionWithProducts = self.dataSource[indexPath.row];

Tiếp theo dòng gọi trước khi vụ tai nạn xảy ra:

[self.collectionView setCollectionViewLayout:[self flowLayout] animated:NO]; 
[self.collectionView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO]; 
[self.collectionView reloadData]; 

Để ngăn chặn điều này chúng tôi quyết định đưa dòng duy nhất của mã mà nguồn thông tin cập nhật dữ liệu vào chủ đề chính.

// Always run on main thread in hope to prevent NSRangeException. 
// Reloading data should happen only sequential. 
dispatch_async(dispatch_get_main_queue(), ^(void) { 
    self.dataSource = newValue; 
}); 

Chúng tôi có rất nhiều [self.collectionView reloadData] trong mã của chúng tôi. Có đáng để chạy chúng trên chủ đề chính không? Nó đã xảy ra một cách nhanh chóng vì vậy nó không nên chặn giao diện người dùng lâu dài.

Có phải là UICollectionViewDelegateFlowLayout phương thức ủy quyền với thuộc tính indexPath luôn được gọi trên hàng đợi nền?

Trả lời

0

Trước hết, tất cả các phương thức UIKIT phải được gọi trên chuỗi chính bao gồm reloadData. Điều này mặc dù sẽ không giải quyết sự cố của bạn. Thứ hai, một nơi nào đó trong mã của bạn có một điều kiện chủng tộc nơi bạn đang gọi reloadData và thay đổi nguồn dữ liệu đồng thời và bạn cần phải tìm ra nơi nó đang xảy ra. Đây là những gì tôi có thể nói mà không nhìn thấy mã thực tế.

Các vấn đề liên quan