标签: performbatchupdates

如何解决这个CollectionView崩溃?

我的应用程序有两个CollectionViewController.在给定时间只能看到一个.

我在故事板上创建了以下结构:两个容器视图相互叠加.每个容器视图都有一个CollectionViewController嵌入式.特定容器视图的可见性确定哪个collectionViewController可见.

这就是问题.两者CollectionViewController都是并行接收数据,但iOS有一个错误,如果一个CollectionViewController performBatchUpdates在不可见的情况下尝试执行插入操作时会导致应用程序崩溃.

为了防止这种情况,我在两个CollectionViewControllers 上创建了一个BOOL标志,这样他们就可以知道它们是否可见并且是否可以执行performBatchUpdates.就像是:

if (self.isThisCollectionViewVisible == NO) return;

[self.collectionView performBatchUpdates:^{
   // bla bla... perform insert,m remove...
Run Code Online (Sandbox Code Playgroud)

这解决了部分问题.但是应用程序继续在以下情况下崩溃:如果我点击按钮切换到不CollectionViewController可见,使其在接收更新时可见.

我的意思是:让我们打电话A给第一个CollectionViewControllerB第二个.A是可见的,此时B是不可见的.B开始接收数据,并试图做一个,performBatchUpdates但因为它是不可见的,这if (self.isThisCollectionViewVisible == NO) return;是阻止performBatchUpdates运行,什么是好的.现在我变得A隐形和B可见.此时标志self.isThisCollectionViewVisible设置为YESperformBatchUpdates使得与此错误的应用程序崩溃:

*断言失败 - [CollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:],/ BuildRoot/Library/Cache/com.apple.xbs/Source/UIKit/UIKit-3512.60.7/UICollectionView.m:4625*由于未捕获的异常而终止应用程序'NSInternalInconsistencyException ',原因:'无效更新:第0部分中的项目数无效.更新后现有部分中包含的项目数(76)必须等于更新前该部分中包含的项目数(70),加上或减去从该部分插入或删除的项目数(插入5个,删除2个),加上或减去移入或移出该部分的项目数(0移入,0移出).

我认为它还CollectionViewController没有准备好并且已经更新以便能够执行performBatchUpdates...而这不是以前不更新数据源的问题,因为它正在更新.

我可以做些什么来防止这种情况发生?

注意:我特别注意到这次崩溃的一些奇怪之处.它说插入了5个元素,删除了2个,但实际上插入了3个元素,0个删除,2个崩溃发生时更改.

iphone ios uicollectionview performbatchupdates

11
推荐指数
1
解决办法
9545
查看次数

与performBatchUpdates崩溃的梦魇

我在面临崩溃的噩梦performBatchUpdatescollection view.

问题基本上是这样的:我在服务器上的目录上有很多图像.我想在上面显示这些文件的缩略图collection view.但必须以异步方式从服务器下载缩略图.当它们到达时,它们将使用以下内容插入到集合视图中:

dispatch_async(dispatch_get_main_queue(),
             ^{
               [self.collectionView performBatchUpdates:^{

                 if (removedIndexes && [removedIndexes count] > 0) {
                   [self.collectionView deleteItemsAtIndexPaths:removedIndexes];
                 }

                 if (changedIndexes && [changedIndexes count] > 0) {
                   [self.collectionView reloadItemsAtIndexPaths:changedIndexes];
                 }

                 if (insertedIndexes && [insertedIndexes count] > 0) {
                   [self.collectionView insertItemsAtIndexPaths:insertedIndexes];
                 }

               } completion:nil];
             });
Run Code Online (Sandbox Code Playgroud)

问题是这个(我想).假设在time = 0,集合视图有10个项目.然后我再向服务器添加100个文件.应用程序查看新文件并开始下载缩略图.随着缩略图下载,它们将被插入到集合视图中.但是因为下载可能需要不同的时间并且这个下载操作是asynchronous,iOS 有时会忘记该集合有多少元素,并且这一灾难性的臭名昭着的消息将导致整个事件崩溃.

***由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第0部分中的项目数无效.更新后的现有部分中包含的项目数(213)必须等于项目数在更新(154)之前包含在该部分中,加上或减去从该部分插入或删除的项目数(插入40个,删除0个)以及加入或减去移入或移出该部分的项目数量(0移入,0搬出去.)

我有一些可疑的证据是,如果我打印数据集上的项目数,我会看到213.因此,数据集匹配正确的数字,而且消息是无意义的.

我以前有过这样的问题,在这里但那是在iOS 7项目.不知何故,问题现在在iOS 8上返回,并且那里的解决方案无效,现在数据集IS IN SYNC.

iphone ios uicollectionview performbatchupdates

11
推荐指数
3
解决办法
9750
查看次数

未调用 iOS 11 UITableView performBatchUpdates 完成关闭

我有一个UITableView显示来自多个 RSS 提要的帖子的聚合提要。每当我的应用从提要中提取新帖子时,我都会创建一个对象,表示更新UITableView当前行所需的所有插入和删除操作。我将这些对象放入一个数组中,用作 FIFO 队列。每隔几秒钟,我就会从这个数组中取出第一个元素,并尝试UITableView使用函数执行所有的插入和删除操作UITableView:performBatchUpdates

这一切都很好……只要用户不UITableView上下滚动。如果正在进行滚动,更新将停止,因为我正在设置一个标志以确保我总是等到最后一组插入/删除完成后再开始下一批,可悲的是,有时,完成关闭UITableView:performBatchUpdates永远不会被调用,因此我的标志永远不会被清除。

这是我用来处理传入更改队列的代码UITableView

@objc func updateFeedPostsTableView() {

    guard feedUpdateQueue.count > 0,
          !feedTableUpdateInProgress else { return }

    feedTableUpdateInProgress = true
    let feedUpdate = feedUpdateQueue.first!
    feedUpdateQueue.remove(at: 0)

    self.aggregatedRSSFeed = feedUpdate.feed

    self.feedPostsTableView.performBatchUpdates ({
        self.feedPostsTableView.deleteRows(at: feedUpdate.indexPathsOfDeletedPosts,
                                           with: .fade)
        self.feedPostsTableView.insertRows(at: feedUpdate.indexPathsOfNewPosts,
                                           with: .top)
        },
        completion: { (success) in
            self.feedTableUpdateInProgress = false
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么UITableView.performBatchUpdates永远无法调用它的完成块?我在这里做错了什么?

这是 iOS 11.2,使用 Xcode 9.2 版。

谢谢!

uitableview ios swift performbatchupdates ios11

5
推荐指数
1
解决办法
6683
查看次数

UICollectionView BatchUpdate边缘情况失败

我在UICollectionView的batchUpdate操作中确定了一个简单的边缘情况,它应该可以工作但是失败了

尝试执行插入并移动到相同的索引路径({length = 2,path = 0 - 2})

我的操作是从[A,B] - > [C,B',A]开始.这是通过更新完成的:

  • 从索引0移动到2
  • 索引1的重新加载
  • 索引为0的插入

显然错误是错误的,插入索引不同于移动TO索引.

我设置了demo以确保这是一个UICollectionView问题,如果你想看到它的运行,这是我的代码:

@implementation ViewController {
  UICollectionView *_collection;
  NSArray *_values;
}

- (instancetype)init
{
  self = [super init];
  if (self) {
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    _collection = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
    _collection.dataSource = self;
    _values = @[@1, @2];
    [_collection registerClass:[UICollectionViewCell class]
      forCellWithReuseIdentifier:@"reuse"];
    [self.view addSubview:_collection];
  }
  return self;
}

- (void)viewDidLoad {
  [super viewDidLoad];
  _collection.frame = self.view.bounds;

  double delayInSeconds = 2.0;
  dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, …
Run Code Online (Sandbox Code Playgroud)

objective-c uikit ios uicollectionview performbatchupdates

4
推荐指数
1
解决办法
558
查看次数