objective-c - Cocoa - 内存问题 - NSTableView

标签 objective-c cocoa memory nstableview

我在当前编写的代码中遇到了内存方面的小问题,我对 cocoa 和面向对象语言编程很陌生,所以目前 Xcode 为我完成了所有内存管理工作,但这对我现在没有帮助.

当前的问题是我正在创建一个 NSTableView,它的每个单元格中的图片以 0.5 秒的间隔更新,这很好,但是每次加载图像时都会创建一个新的 NSImageView 对象(这是我认为的)内存问题是,如果我错了,请纠正我),但是我缺乏解决这个问题的方法。这导致内存使用量每 0.5 秒增加约 5MB,因此大约 10 分钟后,该应用程序将占用我计算机的大部分内存。我不知道如何在创建的 NSImageView 对象无用之后将其删除,而不导致图像在显示过程中延迟...

这是当前代码:

-(void)play_view:(NSInteger)view{
     valid_times_counter = valid_times_counter + 1;
     if(valid_times_counter == ([valid_times count]-2)){
         valid_times_counter = 1;
     }
     [self performSelector:@selector(reload_table_data) withObject:self afterDelay:0.5];
}

-(void)reload_table_data{
    [view_table removeFromSuperview];
    [self addSubview:view_table];
    [view_table reloadData];
    [self play_view:valid_times_counter];
}

- (void)drawRect:(NSRect)dirtyRect
{
NSLog(@"drawing"); //Table being drawn, probably not relevant but just in case ;)

[[NSColor colorWithCalibratedRed:0.01f green:0.40f blue:0.69f alpha:1.00f]setFill];
NSRect bg = NSMakeRect(0, 0, self.frame.size.width, self.frame.size.height);
NSRectFill(bg);

if(level == 1){
    NSLog(@"draw_table Level 1");
    [view_table removeFromSuperview];
    [self setFrameSize:NSMakeSize(2048, 1024)];
    view_table = [[NSTableView alloc]initWithFrame:NSMakeRect(0, self.frame.size.height-1024, 2048, 1024)];
    for(int c = 0; c<4;c++){
        NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i",c]];
        [[column headerCell] setStringValue:[NSString stringWithFormat:@"%i",c]];
        [column setWidth:512.0];
        [view_table addTableColumn:column];
    }
    [view_table setRowHeight:512];
    [view_table setDelegate:(id)self];
    [view_table setDataSource:(id)self];
    [view_table setIntercellSpacing:NSMakeSize(0, 0)];
    [view_table setIdentifier:@"view_table"];
    [view_table reloadData];

    [self addSubview:view_table];

}
else if(level == 2){
    NSLog(@"draw_table Level 2");
    [view_table removeFromSuperview];
    [self setFrameSize:NSMakeSize(4096, 2048)];
    view_table = [[NSTableView alloc]initWithFrame:NSMakeRect(0, self.frame.size.height-2048, 4096, 2048)];
    for(int c = 0; c<8;c++){
        NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i",c]];
        [[column headerCell] setStringValue:[NSString stringWithFormat:@"%i",c]];
        [column setWidth:512.0];
        [view_table addTableColumn:column];
    }
    [view_table setRowHeight:512];
    [view_table setDelegate:(id)self];
    [view_table setDataSource:(id)self];
    [view_table setIntercellSpacing:NSMakeSize(0, 0)];
    [view_table setIdentifier:@"view_table"];
    [view_table reloadData];

    [self addSubview:view_table];
}
else if(level == 3){
    NSLog(@"draw_table Level 3");
    [view_table removeFromSuperview];
    [self setFrameSize:NSMakeSize(8192, 4096)];
    view_table = [[NSTableView alloc]initWithFrame:NSMakeRect(0, self.frame.size.height-4096, 8192, 4096)];
    for(int c = 0; c<16;c++){
        NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i",c]];
        [[column headerCell] setStringValue:[NSString stringWithFormat:@"%i",c]];
        [column setWidth:512.0];
        [view_table addTableColumn:column];
    }
    [view_table setRowHeight:512];
    [view_table setBackgroundColor:[NSColor clearColor]];
    [view_table setDelegate:(id)self];
    [view_table setDataSource:(id)self];
    [view_table setIntercellSpacing:NSMakeSize(0, 0)];
    [view_table setIdentifier:@"view_table"];
    [view_table reloadData];

    [self addSubview:view_table];
}
else if(level == 4){
    NSLog(@"draw_table Level 4");
    [view_table removeFromSuperview];
    [self setFrameSize:NSMakeSize(16384, 8192)];
    view_table = [[NSTableView alloc]initWithFrame:NSMakeRect(0, self.frame.size.height-8192, 16384, 8192)];
    for(int c = 0; c<32;c++){
        NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i",c]];
        [[column headerCell] setStringValue:[NSString stringWithFormat:@"%i",c]];
        [column setWidth:512.0];
        [view_table addTableColumn:column];
    }
    [view_table setRowHeight:512];
    [view_table setDelegate:(id)self];
    [view_table setDataSource:(id)self];
    [view_table setIntercellSpacing:NSMakeSize(0, 0)];
    [view_table setIdentifier:@"view_table"];
    [view_table reloadData];

    [self addSubview:view_table];
}
else if(level == 5){
    NSLog(@"draw_table Level 5");
    [view_table removeFromSuperview];
    [self setFrameSize:NSMakeSize(32768, 16384)];
    view_table = [[NSTableView alloc]initWithFrame:NSMakeRect(0, self.frame.size.height-16384, 32768, 16384)];
    for(int c = 0; c<64;c++){
        NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i",c]];
        [[column headerCell] setStringValue:[NSString stringWithFormat:@"%i",c]];
        [column setWidth:512.0];
        [view_table addTableColumn:column];
    }
    [view_table setRowHeight:512];
    [view_table setBackgroundColor:[NSColor clearColor]];
    [view_table setDelegate:(id)self];
    [view_table setDataSource:(id)self];
    [view_table setIntercellSpacing:NSMakeSize(0, 0)];
    [view_table setIdentifier:@"view_table"];
    [view_table reloadData];

    [self addSubview:view_table];
}


//Problem section
-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{

if([tableView.identifier isEqualToString: @"view_table"]){
    NSLog(@"---------VIEW---------");
    NSView *view = [tableView makeViewWithIdentifier:@"MyView2" owner:self];
    [tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];

    if (view == nil) {
        view = [[NSView alloc]initWithFrame:NSMakeRect(0, 0, 512, 512)];
        NSString *table_id;
        if([tableColumn.identifier integerValue]<10){
            table_id = [NSString stringWithFormat:@"000%@",tableColumn.identifier];
        }
        else if([tableColumn.identifier integerValue]<100){
            table_id = [NSString stringWithFormat:@"00%@",tableColumn.identifier];
        }
        else if([tableColumn.identifier integerValue]<1000){
            table_id = [NSString stringWithFormat:@"0%@",tableColumn.identifier];
        }
        NSString *row_id;
        if(row < 10){
            row_id = [NSString stringWithFormat:@"000%li",row];
        }
        else if(row < 100){
            row_id = [NSString stringWithFormat:@"00%li",row];
        }
        else if(row < 1000){
            row_id = [NSString stringWithFormat:@"0%li",row];
        }

        if([valid_times count]>1){
            image_view2 = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, 512, 512)]; //This gets repeated every 0.5s, and this is what is causing the problem I think...
            NSString *url_str = [self get_url:(valid_times_counter):table_id:row_id];
            NSLog(@"Loading Image from: %@", url_str);
            NSImage *map_tile2 = [[NSImage alloc] initWithContentsOfFile:url_str];
            [image_view2 setImage:map_tile2];
            [view addSubview:image_view2];
        }
        else{
            //No Views found
            NSLog(@"ERROR, NO IMAGES FOUND 348.map_view.h-tableView.viewForTableColumn:row For data %@", [valid_times objectAtIndex:0]);
        }
    }
    return view;

我已经评论了代码中我认为问题所在的部分,有人知道解决方案吗?我想只是更改单元格的内容,而不是每次都重新加载表数据,但我真的不知道知道如何做到这一点。

如果您需要更多详细信息,请询问,我会非常乐意提供任何想法......

最佳答案

在每一行上,您似乎都在重新分配表格 View 。

view_table = [[NSTableView alloc]initWithFrame:NSMakeRect(0, self.frame.size.height-4096, 8192, 4096)];

撇开框架大小的极奇数不谈,您不应该重新创建表格 View 。如果你想重新加载数据,只需调用-reloadData即可,但不要不断删除和添加 TableView 。我不知道你是否使用ARC,但很可能你的问题是你没有释放 TableView 占用的旧内存,而是将一个新实例分配给旧的ivar。旧实例仍然卡在某个地方,但您无法访问它,因为您已经重新分配了指针。

您还在 -drawRect: 中执行所有这些奇怪的重新加载操作,这由于多种原因而非常可怕。

关于objective-c - Cocoa - 内存问题 - NSTableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13634610/

相关文章:

visual-c++ - uintptr_t 可移植替代品

c++ - 如何获取指向函数第一个参数的指针?

objective-c - 如何在不子类化 NSString 的情况下在特定的 [nsstring release] 处设置断点?

ios - objective-c : How to create different shades of a color

ios - 无法找到对象在数组中的位置?

iphone - 尝试在我的应用程序中实现网络错误警报?

macos - 统一从NSTextField、NSComboBox获取值?

objective-c - 我如何在 XCode 4 中使用 NSDocumentController 的子类?

java - 在java中存储 map 哪个内存效率最高?

ios - 为什么 recvfrom 方法的返回值是 4294967295 应该是 0 或 -1?