gpt4 book ai didi

ios - 如何防止 tableview 在 insertRowsAtIndexPaths 和设备旋转期间崩溃

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:58:23 27 4
gpt4 key购买 nike

如果您在行动画期间不断旋转设备,此示例应用会在一段时间后崩溃。我的真实应用有时会在行动画期间的第一次旋转时崩溃。

我应该如何保护我的应用程序在同步行动画旋转期间不崩溃?在动画完成之前,请不要建议禁止旋转。 DataSource 依赖于网络获取,这可能需要 1 到 30 秒的时间,具体取决于用户网络,并且如果用户看到应用程序在横向模式下更好地查看(例如在启动后立即显示),他希望旋转设备。

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{

for (int i = 0; i < 30; i++) {

[NSThread sleepForTimeInterval:0.2]; // imitates fetching and parsing
[self.array addObject:[NSString stringWithFormat:@"cell number %d", i]];

dispatch_async(dispatch_get_main_queue(), ^{

// perform on main
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
});
}
});
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.array.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

// Configure the cell...
cell.textLabel.text = self.array[indexPath.row];

return cell;
}

- (NSMutableArray *)array
{
if (!_array) {
_array = [[NSMutableArray alloc] init];
}
return _array;
}

崩溃报告

2014-02-21 12:47:24.667 RowsAnimationRotate[2062:60b] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2903.23/UITableView.m:1330
2014-02-21 12:47:24.673 RowsAnimationRotate[2062:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (8) must be equal to the number of rows contained in that section before the update (8), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

最佳答案

您实际上已经创建了一个竞争条件。

问题是您在后台线程中操作 self.arrayself.tableView insertRowsAtIndexPaths 在主线程上运行并将访问 self。数组

所以在某些时候self.tableView insertRowsAtIndexPaths(或其他由此调用的tableView方法)在主线程上运行,期望self.array中有一定数量的对象,但是后台线程进入那里并添加另一个...

修复模拟:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{

for (int i = 0; i < 30; i++) {

[NSThread sleepForTimeInterval:0.2]; // imitates fetching and parsing
NSString *myNewObject = [NSString stringWithFormat:@"cell number %d", i]];

dispatch_async(dispatch_get_main_queue(), ^{

// perform on main
[self.array addObject: myNewObject];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
});
}
});

关于ios - 如何防止 tableview 在 insertRowsAtIndexPaths 和设备旋转期间崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21934181/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com