如果您在行动画期间不断旋转设备,此示例应用程序将在一段时间后崩溃.即使在行动画中的第一次旋转,我的真实应用程序也会崩溃.
我应该如何保护我的应用程序在旋转期间与同时行动画一起崩溃?在动画完成之前,请不要建议禁止轮换.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;
}
Run Code Online (Sandbox Code Playgroud)
崩溃报告
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).'
Run Code Online (Sandbox Code Playgroud)
你基本上创造了一个竞争条件.
问题是你self.array在后台线程中操作,而self.tableView insertRowsAtIndexPaths在主线程上运行并将访问self.array.
所以在某些时候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];
});
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3069 次 |
| 最近记录: |