简体   繁体   English

tableView:numberOfRowsInSection:连续调用两次

[英]tableView:numberOfRowsInSection: called twice in a row

I'm getting an error: 我收到一个错误:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. 由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“无效的更新:第0节中的行数无效。

because I'm adding an object to one instance of an array, but then reloading the table view from another instance of what is supposed to be the same array. 因为我要将对象添加到数组的一个实例中,但是随后从应该是同一数组的另一个实例中重新加载表视图。 How can I create a single instance of the array and just pass it around from class to class? 如何创建数组的单个实例,然后在各个类之间传递它? I can do it easily in java, but in Objective-C you can't make static variables so I'm not sure how to do this. 我可以在Java中轻松完成此操作,但是在Objective-C中,您无法创建静态变量,因此我不确定如何执行此操作。

EDIT: more code. 编辑:更多代码。
Here is a method from another class that is called in order to save a file. 这是另一个类的方法,为了保存文件而调用该方法。 I'm using Core Data, so first it adds the file to the context (model), then to the array, then it saves the context. 我正在使用Core Data,因此首先将文件添加到上下文(模型),然后添加到数组,然后保存上下文。 This method is in a class called '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;

}

The following method is in the class that contains the table view--its caled AudioTableViewController 包含表视图的类中的以下方法-其校准的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];

}

The following method adds the object to my model 以下方法将对象添加到我的模型中

- (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;
}

here is the important parts of MusikViewController.h -- it keeps track of recordingsArray and downloadsArray 这是MusikViewController.h的重要部分-跟踪recordsArray和downloadsArray

@interface MusikerViewController : UIViewController {
}

NSMutableArray   *recordingsArray;
NSMutableArray   *downloadsArray;

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

and MusikViewController.m 和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;
}

and some AudioTableViewController methods 和一些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;
            }

If your data model changes you need to either reload the tableView, or insert/remove the rows otherwise the tableview will freak out on you. 如果您的数据模型发生更改,则需要重新加载tableView或插入/删除行,否则tableview会对您不满意。 It doesn't matter how many times tableView:numberOfRowsInSection is called, your data model can't return a different number without first reloading or updating the tableview. 调用tableView:numberOfRowsInSection的次数无关紧要,您的数据模型必须先重新加载或更新tableview才能返回不同的数字。

Based on your logging my guess is that your downloads array is changing quantities. 根据您的记录,我的猜测是您的下载阵列正在改变数量。 It makes it past the NSLog then dies in _endCellAnimationsWithContext. 它经过NSLog,然后在_endCellAnimationsWithContext中死亡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM