Ios UITableView中的NSMutableArray

Ios UITableView中的NSMutableArray,ios,objective-c,uitableview,Ios,Objective C,Uitableview,我只是被困在这里,我不知道我做错了什么。我对目标c很陌生。在我的应用程序中,我使用UITableView和NSMutableArray解析RSS提要中的数据。当用户单击tableview中的segment控件时,我想用新数据刷新整个表。我在表头部分添加了段控件,它可以在段索引更改时更改值 现在的问题是,当我单击段控件时,它会在tableview中添加新行,而不是刷新整个表。代码如下: - (void)addEarthquakesToList:(NSArray *)earthquakes

我只是被困在这里,我不知道我做错了什么。我对目标c很陌生。在我的应用程序中,我使用
UITableView
NSMutableArray
解析RSS提要中的数据。当用户单击tableview中的segment控件时,我想用新数据刷新整个表。我在表头部分添加了段控件,它可以在段索引更改时更改值

现在的问题是,当我单击段控件时,它会在tableview中添加新行,而不是刷新整个表。代码如下:

- (void)addEarthquakesToList:(NSArray *)earthquakes
    {
    //NSInteger startingRow = [self.earthquakeList count];
    NSInteger earthquakeCount = [earthquakes count];
    NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:earthquakeCount];
    NSLog(@"%d",earthquakeCount);

    for (NSInteger row = 0; row < (earthquakeCount); row++)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
        [indexPaths addObject:indexPath];
    }

    [self.earthquakeList addObjectsFromArray:earthquakes];
    [self.tableView  insertRowsAtIndexPaths:indexPaths
                           withRowAnimation:UITableViewRowAnimationAutomatic];
}

以下是我的tableView数据源方法:

- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    // The number of rows is equal to the number of earthquakes in the array.
    return [self.earthquakeList count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *kEarthquakeCellID = @"EarthquakeCellID";
    citsTableViewCell *cell = (citsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kEarthquakeCellID];

    //Get the specific earthquake for this row.
    citsFuelFinder *earthquake = (self.earthquakeList)[indexPath.row];
    [cell configureWithEarthquake:earthquake];
    return cell;
}

事实上,当尝试在段控件中包含以下内容时:

- (void)segmentedControlHasChangedValue
{
    int product;
    product = fuelType.selectedSegmentIndex;

    switch (product)
    {
        case 0:
            productName=1;
            [locationManager startUpdatingLocation];
            break;

        case 1:
            productName=2;
            //[self.earthquakeList removeLastObject];
            if (![self.earthquakeList count])
            {
                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:0]
                              withRowAnimation:UITableViewRowAnimationRight];
            }
            else
            {
                NSMutableArray *indexPathsToDelete = [[NSMutableArray alloc] init];
                for(unsigned int i = 0; i < [self.earthquakeList count]; i++)
                {
                    [indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i
                                                                     inSection:0]];
                }
                //[self.tableView beginUpdates];
                //[self.earthquakeList removeAllObjects];
                [self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
                                      withRowAnimation:UITableViewRowAnimationFade];
                //[self.tableView endUpdates];
                [self.tableView reloadData];
                //[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
            }
            [locationManager startUpdatingLocation];
            break;

        case 2:
            productName=4;
            [locationManager startUpdatingLocation];
            break;

        case 3:
            productName=5;
            [locationManager startUpdatingLocation];
            break;

        default:
            break;
    }
}
-(void)分段控件已更改值
{
int产品;
产品=fuelType.selectedSegmentIndex;
交换机(产品)
{
案例0:
productName=1;
[locationManager startUpdatingLocation];
打破
案例1:
productName=2;
//[自我地震师移除目标];
如果(![self.earthquakeList count])
{
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:0]
withRowAnimation:UITableViewRowAnimationRight];
}
其他的
{
NSMUTABLEARRY*indexPathsToDelete=[[NSMUTABLEARRY alloc]init];
for(无符号整数i=0;i<[self.earthquakeList count];i++)
{
[indexPathsToDelete addObject:[NSIndexPath indexPathForRow:i
不确定:0]];
}
//[self.tableView开始更新];

//[自地震师移除所有对象]; [self.tableView deleteRowsAtIndexPaths:indexPathsToDelete withRowAnimation:UITableViewRowAnimationFade]; //[self.tableView endUpdates]; [self.tableView重载数据]; //[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]with RowAnimation:YES]; } [locationManager startUpdatingLocation]; 打破 案例2: productName=4; [locationManager startUpdatingLocation]; 打破 案例3: productName=5; [locationManager startUpdatingLocation]; 打破 违约: 打破 } }
我得到这个错误:

由于未捕获异常而终止应用程序 'NSInternalInconsistencyException',原因:'无效更新:无效 节0中的行数。表中包含的行数 更新(15)后的现有节数必须等于 更新(15)之前该节中包含的行,加号或减号 从该节插入或删除的行数(插入0, 15)并加上或减去移入或移出的行数 该部分(0移入,0移出)。' *第一次抛出调用堆栈:(0x2e332e83 0x3868f6c7 0x2e332d55 0x2ecdb0af 0x30c8a34d 0x30cb083f 0x6d2d9 0x30aebda3 0x30aebd3f) 0x30aebd13 0x30ad7743 0x30bf7c59 0x30bf7a27 0x30cbca25 0x30aaf1a1 0x30ae69fd 0x30ae63ab 0x30abbd79 0x30aba569 0x2e2fdf1f 0x2e2fd3e7 0x2E2FBD7 0x2e266471 0x2e266253 0x32fa02eb 0x30b1b845 0x6948d 0x38b88ab7)


非常感谢任何帮助

更新tableview的源数组,无需插入新行

[self.earthquakeList addObjectsFromArray:earthquakes];
[self.tableView reloadData];

如果向数据源数组中添加元素,则表视图中的行数将自动更新。您不需要插入行。只需插入元素。将您的方法实现为:

- (void)addEarthquakesToList:(NSArray *)earthquakes 
{
   [self.earthquakeList addObjectsFromArray:earthquakes];
   [self.tableview reloadData];
} 
呃,而不是

[self.tableView  insertRowsAtIndexPaths:indexPaths
                       withRowAnimation:UITableViewRowAnimationAutomatic];
试一试


无论如何。。。。至少对我来说,您的代码片段仍然不足以找到您的问题

但既然你说:
当用户单击tableview中的segment控件时,我想用新数据刷新整个表。

如果我必须制作一个包含4个段的分段表格视图,为不同的段显示不同的数据,我会这样做:

注:这是一个基本示例。它不符合您的特定代码,但应该可以让您放弃使用IndExpath的逻辑,或者从数组中手动添加/删除对象,而是适当地使用
tableView reloadData

- (void)viewDidLoad
{
    [super viewDidLoad];

    //declare NSArray *arrFirst, *arrSecond, *arrThird, *arrFourth, *arrSelected
    //in the .h file

    arrFirst = [[NSArray alloc] initWithObjects:@"eins",@"zwei",@"drei",@"vier",@"fünf",@"sechs", nil];
    arrSecond = [[NSArray alloc] initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eigth",@"nine", nil];
    arrThird = [[NSArray alloc] initWithObjects:@"uno",@"dos",@"tres",@"cuatro",@"cinco", nil];
    arrFourth = [[NSArray alloc] initWithObjects:@"ek",@"do",@"teen",@"chaar",@"paach",@"che",@"saat", nil];

    arrSelected = arrFirst;
}


我也可以使用单个数组来完成此操作,首先刷新旧数组内容:
arrSelected=nil

然后将新元素放入该数组中(使用某些逻辑从某个源中)
最后:

myTableView重新加载数据

您选择第二个段时,崩溃出现了吗
因此,以下代码会导致错误

[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
                                  withRowAnimation:UITableViewRowAnimationFade];
使用deleteRowsAtIndexPaths或InsertRowsatindExpaths时,必须确保数据源的长度与tableView的当前行匹配。


例如:您的tableView已经有10行,现在您需要删除2行,您应该首先从数据源数组中删除2个数据对象,然后调用deleteRowsAtIndexPaths。

尝试这些替换,并在以后给我们一些反馈(特别是如果任何NSAssert“崩溃”了您的应用程序):


因此,您要做的是始终让表在
self.earthquakeList
中显示数据,并在更新时清除所述数据?我理解正确吗?是的,完全正确。谢谢,无需插入新行。您可以更改数据源(earthquakeList)并重新加载TableView抱歉,我不确定您的意思。请你再详细一点…请编辑你的帖子,将这两种方法包括在内-numberOfRowsInSection&-CellForRowAtIndexPath谢谢,我尝试了你的第一个建议,但没有成功,它的行号错误。我尝试了-(void)clearData{[self.tableVie]
- (void)viewDidLoad
{
    [super viewDidLoad];

    //declare NSArray *arrFirst, *arrSecond, *arrThird, *arrFourth, *arrSelected
    //in the .h file

    arrFirst = [[NSArray alloc] initWithObjects:@"eins",@"zwei",@"drei",@"vier",@"fünf",@"sechs", nil];
    arrSecond = [[NSArray alloc] initWithObjects:@"one",@"two",@"three",@"four",@"five",@"six",@"seven",@"eigth",@"nine", nil];
    arrThird = [[NSArray alloc] initWithObjects:@"uno",@"dos",@"tres",@"cuatro",@"cinco", nil];
    arrFourth = [[NSArray alloc] initWithObjects:@"ek",@"do",@"teen",@"chaar",@"paach",@"che",@"saat", nil];

    arrSelected = arrFirst;
}
- (IBAction)mySegmentsAct:(UISegmentedControl *)sender
{
    switch (sender.selectedSegmentIndex)
    {
        case 0:
            arrSelected = arrFirst;
            break;
        case 1:
            arrSelected = arrSecond;
            break;
        case 2:
            arrSelected = arrThird;
            break;
        case 3:
            arrSelected = arrFourth;
            break;
        default:
            arrSelected = nil;
            break;
    }

    [myTableView reloadData];
}
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
    return [arrSelected count];
}

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

    if(cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
                                     reuseIdentifier:CellIdentifier];
    }
    cell.textLabel.text = (arrSelected)[indexPath.row];
    return cell;
}
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
                                  withRowAnimation:UITableViewRowAnimationFade];
- (void)addEarthquakesToList:(NSArray *)earthquakes
{
    // data checking
    NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
    NSAssert(self.tableView != nil, @"tableView cannot be nil!");
    NSAssert(earthquakes != nil, @"earthquakes cannot be nil!");

    // relevant implementation
    [self.earthquakeList addObjectsFromArray:earthquakes];
    [self.tableView reloadData];
}

- (void)segmentedControlHasChangedValue
{
    // data checking
    NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
    NSAssert(self.tableView != nil, @"tableView cannot be nil!");
    NSAssert(fuelType != nil, @"fuelType cannot be nil!");
    NSAssert(locationManager != nil, @"locationManager cannot be nil!");

    // relevant implementation
    switch (fuelType.selectedSegmentIndex)
    {
        case 0:
            productName=1; // what is this?
            [locationManager startUpdatingLocation];
            break;

        case 1:
            productName=2;
            [self.earthquakeList removeAllObjects];
            [locationManager startUpdatingLocation];
            break;

        case 2:
            productName=4;
            [locationManager startUpdatingLocation];
            break;
        case 3:
            productName=5;
            [locationManager startUpdatingLocation];
            break;

        default:
            break;
    }

    [self.tableView reloadData]; // if you want to change the data whenever the user changes the UISegmentedControl to any new value, leave this here.
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    // data checking
    NSAssert(self.earthQuakeList != nil, @"earthQuakeList cannot be nil!");
    NSAssert(self.tableView != nil, @"tableView cannot be nil!");

    // relevant implementation
    [self.earthquakeList removeAllObjects];
    [self.tableView reloadData];
}