刷新表时应用程序崩溃(可能是tableView上的调用endUpdates导致崩溃)

时间:2013-03-24 12:17:25

标签: iphone ios objective-c uitableview

遇到这篇文章但没有解决我的问题。

iPhone app crashing on [self.tableView endUpdates]

从报纸网站获得UITableViewloads篇文章。首先load有效 正如所料,当我再次使用UIRefreshControlfetch文章时,我的应用程序崩溃了 何时(animatinginserting rows

错误:

enter image description here

代码:

- (void)insertRowsWithAnimation
{
    NSMutableArray *indexPaths = [NSMutableArray array];
    NSInteger i = self.latestArticlesArray.count - self.latestArticlesArray.count;

    for (NSDictionary *dict in self.latestArticlesArray) {
        [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        i++;
    }
    [self.tableView beginUpdates];
    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationMiddle];
    [self.tableView endUpdates];
}

- (void)fetchEntries
{
    UIView *currentTitleView = [[self navigationItem] titleView];
    UIActivityIndicatorView *aiView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

    [[self navigationItem] setTitleView:aiView];
    [aiView startAnimating];

    void (^completionBlock) (NSArray *array, NSError *err) = ^(NSArray *array, NSError *err) {
        if (!err) {
            [[self navigationItem] setTitleView:currentTitleView];
            self.latestArticlesArray = [NSArray array];
            self.latestArticlesArray = array;
            [self insertRowsWithAnimation];
        }
    };
    [[Store sharedStore] fetchArticlesWithCompletion:completionBlock];
}

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

如果您想查看更多方法,请告诉我们。希望你能帮忙。从我到目前为止所学到的,我认为帖子的数量已经改变,因此表格预计会有另外数量的文章显示出来?

3 个答案:

答案 0 :(得分:2)

该行

NSInteger i = self.latestArticlesArray.count - self.latestArticlesArray.count;

i设置为 ,因此使用空数组调用insertRowsAtIndexPaths

我假设您的意图是使用新添加的行的行号来调用insertRowsAtIndexPaths,但是在替换

中的数组之前必须记住旧数据
self.latestArticlesArray = array;

但请注意,既然你要替换整个数组,你也可以调用

[self.tableView reloadData];

而不是beginUpdates / insertRowsAtIndexPaths / endUpdates


更新:我的第一个分析是错误的(而且wattson12是正确的)。正如您在评论中所说,您只需要一个简单的动画即可删除所有先前的行并在获取后插入新行。这可以这样做:

- (void)replaceArticlesWithAnimation:(NSArray *)articles
{
    NSUInteger oldCount = [self.latestArticlesArray count];
    self.latestArticlesArray = articles;
    NSUInteger newCount = [self.latestArticlesArray count];

    [self.tableView beginUpdates];
    for (NSUInteger i = 0; i < oldCount; i++) {
        [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    for (NSUInteger i = 0; i < newCount; i++) {
        [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    [self.tableView endUpdates];
}

并在fetchEntries中致电

if (!err) {
    [[self navigationItem] setTitleView:currentTitleView];
    [self replaceArticlesWithAnimation:array];
}

答案 1 :(得分:2)

它第一次加载的原因是因为每次都要插入多行,所以在第一次运行时,行数从0变为数组中的计数(在完成块中),并调用insertRows具有多个索引路径等于数组的计数。

第二次调用它时,您正在插入新行,但是您没有更新计数以反映新的总和。您应该将现有数组添加到完成块中返回的数组,并在numberOfRowsInSection中返回该组合数组的计数

答案 2 :(得分:1)

dispatch_async(dispatch_get_main_queue(), ^(void){
        //Run UI Updates
    });