NSTableView重用行与旧数据

时间:2013-07-02 04:37:46

标签: objective-c cocoa nstableview

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

这是我自定义TableViewCell的代码:

HomeworkTableViewCell.h:

#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

HomeworkTableViewCell.m:

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

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

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

编辑: 这是我用uasi的建议想出来的:

{{1}}

2 个答案:

答案 0 :(得分:4)

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

相反,您可以使用NSTableViewDelegate的{​​{1}}方法:

-tableView:viewForTableColumn:row:

答案 1 :(得分:2)

我知道这个问题有点陈旧,但我只是把它放在那里,像我这样的人一直在寻找解决方案。

if ([self.tableView respondsToSelector:@selector(usesStaticContents)])
  //Method currenly only available on OS X 10.10 or later
  {
    //This is used to prevent table view rows from being reused
    /*From:https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/
      Normally, a table view will only keep around a subset of the total number of rows potentially available (in general, this is limited to the visible region, plus some overdrawn allowance for responsive scrolling). A static table view keeps all views added to the table around when usesStaticContents=YES
      */
      //Also check out: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/TableViewOverview/TableViewOverview.html

     self.tableView.usesStaticContents = YES;

   }

注意:使用此解决方案,您的应用可能会显示更高的内存利用率(原因很明显)。但是,在我的测试中,它并没有太大差异,您的里程可能会有所不同。