iphone - 向 UITableView 插入行崩溃

标签 iphone objective-c ios uitableview insert

我正在开发一个应用程序,需要在后台加载一些数据,然后使用 UITableView 显示数据。 这是一些代码,
在后台加载数据:

- (void)loadRelatedItems 
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    for (NSString *mediaType in allMediaTypes) 
    {
        [self performSelector:@selector(loadRelatedItems:) withObject:mediaType];
    }

    NSString *notificationName = [CommonFunction allRelatedItemsLoadedNotificationName];
    [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:nil];

    [pool release];
}

- (void)loadRelatedItems:(NSString *)mediaType 
{
   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

   for (NSString *keyword in _keywords) 
   {
      NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@&mediaType=%@&keyword=%@", API, mediaType, keyword]];
      NSMutableArray *items = [CommonFunctions arrayFromURL:URL];

      if ([items count] == 0) continue;

      NSString *notificationName = [CommonFunction partialRelatedItemsLoadedNotificationName];
      NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:items, @"items", mediaType, @"mediaType", nil];
      [[NSNotificationCenter defaultCenter] postNotificationName:notificationName object:self userInfo:dic];   
   }

   [pool release];
}

在 UITableView 中显示数据:

- (void)didFinishLoadPartialRelatedItems:(id)sender 
{
  NSDictionary *dic = [sender userInfo];
  NSString *mediaTypeString = [dic objectForKey:@"mediaType"];
  NSMutableArray *items = [dic objectForKey:@"items"];


  dispatch_async(dispatch_get_main_queue(), ^{

    if ([_relatedItems count] == 0) 
    {
        [_relatedItems setObject:items forKey:mediaTypeString];
        [_tableView reloadData];
    } 
    else 
    {
        NSMutableArray *mediaTypeItems = [_relatedItems objectForKey:mediaTypeString];

        if (mediaTypeItems) 
        { 
           // section exist
           NSInteger section =[[[_relatedItems allKeys] sortedArrayUsingSelector:@selector(mediaTypeCompare:)] indexOfObject:mediaTypeString];
           NSMutableArray *indexPaths = [NSMutableArray array];

           for (NSMutableDictionary *item in items) 
           {
               [mediaTypeItems addObject:item];
               NSInteger newRow = [mediaTypeItems indexOfObject:item];
               NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:newRow inSection:section];
               [indexPaths addObject:newIndexPath];
           }

           [_tableView beginUpdates];
           [_tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
           [_tableView endUpdates]; 
        }
        else 
        { 
            // new section

            [_relatedItems setObject:items forKey:mediaTypeString];
            NSInteger section =[[[_relatedItems allKeys] sortedArrayUsingSelector:@selector(mediaTypeCompare:)] indexOfObject:mediaTypeString];
            NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];
            [_tableView beginUpdates];
            [_tableView insertSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
            [_tableView endUpdates];

        }

    }
});
}

#pragma mark -
#pragma mark Table Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if ([_relatedItems count] == 0) {
    return 1;
} else {

    return [_relatedItems count];
}
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{

NSArray *allTitles = [[_relatedItems allKeys] sortedArrayUsingSelector:@selector(mediaTypeCompare:)];
NSString *title = [allTitles objectAtIndex:section];
NSDictionary *allMediaTypeDisplayNames = [CommonFunction allMediaTypeDisplayNames];

return [allMediaTypeDisplayNames objectForKey:title];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([_relatedItems count] == 0) {
    return 0;
}
NSArray *allTitles = [[_relatedItems allKeys] sortedArrayUsingSelector:@selector(mediaTypeCompare:)];

NSString *title = [allTitles objectAtIndex:section];
NSInteger rowsCount = [[_relatedItems objectForKey:title] count];

return rowsCount;
}

我很困惑,它有时工作正常,但有时它崩溃并显示消息:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1030
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections.  The number of sections contained in the table view after the update (0) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).

有什么问题吗?请帮忙。

最佳答案

请确保更新后,您的节数应等于更新前的节数。

根据您的代码:

部分的数量定义如下:

if ([_relatedItems count] == 0) {
    return 1;
} else {

    return [_relatedItems count];
}

在这种情况下,您正在创建新部分,对吗?

else { // new section

            [_relatedItems setObject:items forKey:mediaTypeString];
            NSInteger section =[[[_relatedItems allKeys] sortedArrayUsingSelector:@selector(mediaTypeCompare:)] indexOfObject:mediaTypeString];
            NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];
            [_tableView beginUpdates];
            [_tableView insertSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
            [_tableView endUpdates];

        }

如果您正在创建新部分,那么您的[_latedItems count] 将会增加。因此,请确保插入后您的计数也应该相同。

对吗?

试试这个:

if ([_relatedItems count] == 0) {
        return 1;
    } else {
        if([_relatedItems count]>previousCount)
            return [_relatedItems count];
        return previousCount;
    }

当您对 [_latedItems]; 进行任何更新时,请更改更新您的 previousCount ..这将得到解决

关于iphone - 向 UITableView 插入行崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13965591/

相关文章:

iphone - 从文件取消归档时 NSOrderedSet addObject 出现问题

objective-c - 在Objective-C中找到另一个不区分大小写的字符串

ios - 'UITableViewCell' 没有名为 'nameLabel' 的成员

iPhone MKMapView注释观察者可选择一次

iphone - 将图像数据转换为字符数组

iphone - 在屏幕上移动图像时制作动画图像的简单方法?

objective-c - 如何创建一个类似 iTunes 迷你播放器的 NSWindow(总是在最上面但没有焦点!)

ios - 谁应该负责显示带有登录表单的模式对话框?

ios - native UITextField 安全文本输入强制英语(美国)键盘

ios - 如何在将 View Controller 推送到另一个 View Controller 时处理 UIParallaxDimmingView?