tableView:numberOfRowsInSection:连续两次调用

时间:2013-08-09 05:26:49

标签: ios objective-c uitableview

我收到了一个错误:

  

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第0部分中的行数无效。

因为我正在向一个数组实例添加一个对象,然后从另一个应该是同一个数组的实例重新加载表视图。如何创建数组的单个实例并将其从类传递给类?我可以在java中轻松完成,但是在Objective-C中你不能创建静态变量,所以我不知道如何做到这一点。

编辑:更多代码。
这是从另一个类中调用以保存文件的方法。我正在使用Core Data,所以首先它将文件添加到上下文(模型),然后添加到数组,然后它保存上下文。此方法位于名为“Player”的类中

-(BOOL)saveRecording {
    Bank *B = [MusikerViewController daBank];
    AudioTableViewController *ATVC2 = [MusikerViewController ATVControl];
    NSLog(@"Place A");
   AudioFile *myAudioFileMusicX314 = [[B addAudioFileEntityToModelWithDate:myDate andURLString:strPath] retain];
    NSLog(@"Place B");

    myAudioFileMusicX314.type = true;

    [ATVC2 addAudioEntityToArray:myAudioFileMusicX314];
    NSLog(@"Place C ***********************************************");

    if(![B saveContext]) { //save context after adding file to keep consistancy
        NSLog(@"addAudioFileEntityToModel is returning a nil managedObjectContext");
        return NO;
    }
    NSLog(@"Place D");

    [myDate release];
    [strPath release];
    [myAudioFileMusicX314 release];
    [ATVC2 release];
    NSLog(@"Place E");

    return YES;

}

以下方法在包含表视图的类中 - 它的caled AudioTableViewController

    -(void)addAudioEntityToArray:(AudioFile *)event {
    NSIndexPath *indexPath;

    if(event.type) {
        [[MusikerViewController recordingsArray] addObject:event];//self?
        indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    }

    else {
        [[MusikerViewController downloadsArray] addObject:event];
        indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
    }

    [[self tableView] setEditing:YES animated:NO];
   [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                          withRowAnimation:UITableViewRowAnimationNone];

}

以下方法将对象添加到我的模型

- (AudioFile *)addAudioFileEntityToModelWithDate:(NSDate *)theD andURLString:(NSString *)str {
    NSLog(@"addAudio...WithDate -- called");
    sound = (AudioFile *)[NSEntityDescription insertNewObjectForEntityForName:@"AudioFile" inManagedObjectContext:managedObjectContext];

    sound.creationDate = theD;
    sound.soundPath = str; //set the sound path to the sound file's url
    [self alertForTitle];

    NSLog(@"No problems yet at place D - addaudio...String, sound title is %@", sound.title);
    NSLog(@"Context at addAudioFileEntityToModel is: %@", managedObjectContext);

    return sound;
}

这是MusikViewController.h的重要部分 - 它跟踪recordingsArray和downloadsArray

@interface MusikerViewController : UIViewController {
}

NSMutableArray   *recordingsArray;
NSMutableArray   *downloadsArray;

+ (NSMutableArray *)recordingsArray;
+ (NSMutableArray *)downloadsArray;

和MusikViewController.m

 + (NSMutableArray *)recordingsArray {
    NSLog(@"recordingsArray called");

    if(!recordingsArray) {
        recordingsArray = [[NSMutableArray alloc] init];
        NSMutableArray *bigTempArray = [[[[Bank alloc] init] autorelease] getFetchArray]; //change this
        for(AudioFile *af in bigTempArray)
            if(af.type) {
                [recordingsArray addObject:af];
            }
        NSLog(@"recordingsArray exists");
    }
    return recordingsArray;
}

+ (NSMutableArray *)downloadsArray {
    NSLog(@"recordingsArray called");

    if(!downloadsArray) {
        downloadsArray = [[NSMutableArray alloc] init];
        // if(!bigTempArray)
        NSMutableArray *bigTempArray = [[[[Bank alloc] init] autorelease] getFetchArray];
        for(AudioFile *af in bigTempArray)
            if(!af.type) {
                [downloadsArray addObject:af];
            }
    }
    return downloadsArray;
}

和一些AudioTableViewController方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    NSLog(@"Place F");    

    if(section == 0) {
    return [[MusikerViewController recordingsArray] count];
    }
    else if (section == 1) {
        return [[MusikerViewController downloadsArray] count];
    }

}

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {

        static NSString *CellIdentifier = @"Cell";

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        }

        AudioFile *event;
        if(indexPath.section == 0) {
        event = (AudioFile *)[[MusikerViewController recordingsArray] objectAtIndex:indexPath.row];
        } else if (indexPath.section == 1) {
            NSLog(@"downAry indexPath caled at cellForRow...Path");
            event = (AudioFile *)[[MusikerViewController downloadsArray] objectAtIndex:indexPath.row];
        }
        cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
        if(event.title) {
        cell.detailTextLabel.text = [Player dateString:event.creationDate];
        cell.textLabel.text = event.title;
        } else {
            cell.textLabel.text = [Player dateString:event.creationDate];
            cell.detailTextLabel.text = nil;
        }

        return cell;
    }


            - (void)viewDidLoad //viewDidLoad for AudioTableViewController
            {
                [[self tableView] reloadData];
                NSLog(@"viewDidLoad called for AudioTableViewController");

                [super viewDidLoad];

                self.title = @"Audio Files";//put this in application delegate

                // Set up the buttons.
                self.navigationItem.leftBarButtonItem = self.editButtonItem;
            }

1 个答案:

答案 0 :(得分:0)

如果你的数据模型发生了变化,你需要重新加载tableView,或者插入/删除行,否则tableview会让你感到害怕。调用tableView:numberOfRowsInSection多少次并不重要,如果没有先重新加载或更新tableview,您的数据模型将无法返回不同的数字。

根据您的记录,我的猜测是您的下载数组正在改变数量。它使它通过NSLog然后在_endCellAnimationsWithContext中死掉。