我为学校创建了一个表格视图,作为应用程序的一部分,该视图允许学生输入作业,然后将其选中并消失,就像提醒应用程序一样。我遇到的问题是,当我检查一行以使其消失时,我从表中删除了该行,并从保存所有HomeworkItem的数组中删除了HomeworkItem及其数据。但是,下次我尝试添加一行(通过单击末尾的缓冲区行)时,添加的新行是我刚刚删除的同一行,具有相同的HomeworkItem信息,即使该HomeworkItem具有已从阵列中删除。我记得读过NSableViews试图重用行以提高内存效率,但是我不明白为什么行会挂在旧信息上。有人可以解释为什么会发生这种情况,或者我该如何解决?

这是自定义TableViewCell的代码:

HomeworkTableViewCell.h:

#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"
#import "ClassViewController.h"

@class ClassViewController;
@class AppDelegate;

@interface HomeworkTableCellView : NSTableCellView

@property (weak) IBOutlet NSTextField *assignmentName;
@property (weak) IBOutlet NSDatePicker *dueDatePicker;
@property BOOL isCompleted;
@property NSInteger rowNumber;
@property (weak) AppDelegate *ad;
@property NSTableView *superTable;
@property ClassViewController *superCVC;

- (void)setSuperRow:(id)sender;
- (IBAction)completed:(id)sender;
- (IBAction)dateChanged:(id)sender;

@end


家庭作业TableViewCell.m:

#import "HomeworkTableCellView.h"

@implementation HomeworkTableCellView

- (id)initWithCoder:(NSCoder *)aDecoder{
//    NSLog(@"I");//TEST
    self = [super initWithCoder:aDecoder];
    if (self) {
        self.ad = [[NSApplication sharedApplication]delegate];
        self.superTable = self.ad.classViewController.homeworkTable;
        self.superCVC = self.ad.classViewController;
        self.isCompleted = NO;
    }
    return self;
}

- (void)setSuperRow:(id)sender{
    [self.superCVC updateRow:sender];
}
- (IBAction)completed:(id)sender{
    self.isCompleted = !self.isCompleted;
    [self.superCVC changeStateOfHomeworkItem:self];
    [self.superCVC updateRow:sender];
}
- (IBAction)dateChanged:(id)sender{
    [self.superCVC updateRow:sender];
    [self.superCVC editDateOfHomeworkItem];
}
@end


以下是出现问题的视频的链接:http://youtu.be/Ot8w5oz8L-E

控制台中的文本表示删除对象后家庭作业数组中的内容,因此很明显,已删除的对象不再存在。

编辑:
这是我根据uasi的建议想到的:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    HomeworkTableCellView *HTCV = [self.homeworkTable makeViewWithIdentifier:tableColumn.identifier owner:self];//maybe owner:nil
    [HTCV.assignmentName setStringValue: @""];
    [HTCV.dueDatePicker setDateValue: [[NSDate alloc]initWithString:@"1-1-1 0:0:0 +0000"]];//false date for testing
    HTCV.isCompleted = NO;
    [HTCV.checkBox setState:NSOffState];

    [self updateTableView];

    return HTCV;
}

- (void)updateTableView{
    for (int i = 0; i < self.ad.currentSubject.homework.count; i++) {
        HomeworkTableCellView *HTCV = [self.homeworkTable viewAtColumn:0 row:i makeIfNecessary:NO];
        HomeworkItem *HI = [self.ad.currentSubject.homework objectAtIndex:i];
        [HTCV.dueDatePicker setDateValue: HI.dueDate];
        [HTCV.assignmentName setStringValue: HI.details];
    }
}

最佳答案

您可能不使用-tableView:objectValueForTableColumn:row:进行表格单元格视图。虽然文档声称“此方法是强制性的”,但对<AppKit/NSTableView.h>中找到的方法的注释说:“此方法对于“基于单元的” TableView是必需的,而对于“基于视图的” TableView是可选的。

相反,您可以使用NSTableViewDelegate-tableView:viewForTableColumn:row:方法:



- (NSView *)tableView:(NSTableView *)tableView
   viewForTableColumn:(NSTableColumn *)tableColumn
                  row:(NSInteger)row
{
  // Instantiate a view object from XIB or reuse one in the cache.
  NSString *identifier = @"YOUR_CELL_VIEW_IDENTIFIER";
  HomeworkTableCellView *HTCV = [tableView makeViewWithIdentifier:identifier owner:nil];

#if 0
  // If you have not put a HomeworkTableCellView object in a XIB with identifier,
  // you'll need to create an instance programatically like this;
  // It seems not to be the case, though.
  if (HTCV == nil) {
    HTCV = [[HomeworkTableCellView alloc] initWithFrame:NSZeroRect];
    HTCV.identifier = identifier;
  }
#endif

  // Do initialization anything specific to a row here,
  // because the view's -init{WithCoder:,WithFrame:} method
  // is not always called for each row due to the cache mechanism.
  HomeworkItem *HI = [self.homeworkArray objectAtIndex:row];
  [HTCV.dueDatePicker setDateValue: HI.dueDate];
  // ...

  return HTCV;
}

09-19 07:43