我需要帮助找出如何将NSArray的内容显示到NSTableView中。我的NSArray充满了(或者至少我认为是)目录中的文件名。我使用NSFileManager获取目录中文件的名称,然后将该信息加载到NSArray中。但我无法弄清楚如何将NSArray加载到NSTableView中。
AppDelegate.h
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet NSTableView *tableView;
NSArray *list;
IBOutlet NSTextField *text;
NSFileManager *manager;
NSString *path;
NSString *pathFinal;
}
@property (assign) IBOutlet NSWindow *window;
- (IBAction)listArray:(id)sender;
@end
AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
return [list count];
}
- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(int)row
{
return [list objectAtIndex:row];
}
- (IBAction)listArray:(id)sender {
path = @"~/Library/Application Support/minecraft/bin/";
pathFinal = [path stringByExpandingTildeInPath];
list = [manager directoryContentsAtPath:pathFinal];
[tableView reloadData];
}
- (void)dealloc
{
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
}
@end
答案 0 :(得分:1)
有两种方法可以执行此操作:Cocoa Bindings使用NSArrayController
或在对象中实施NSTableDataSource
协议,并将该对象指定为表格视图datasource
。< / p>
看起来你已经半实现了NSTableViewDataSource
方法。您需要将协议声明添加到您的接口,以指示您的AppDelegate
对象实现协议:
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource>
您已经实现了所需的数据源方法,因此理论上一切都应该正常,但您可能没有将AppDelegate
对象设置为表视图的datasource
。您可以在代码中执行此操作:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[tableView setDatasource:self];
}
或者,您可以通过将表格视图的datasource
插座设置为AppDelegate
实例,在Interface Builder中指定数据源。
但是,您遇到的主要问题是您正在为list
ivar分配一个自动释放的对象,并且在表视图重新加载之前它已被释放。
您的listArray
方法存在问题。 path
和pathFinal
没有理由成为实例变量。它们只使用一次,因此应该是本地范围的。实际上,由于path
是常量,因此应单独声明:
//this should go in the top of your .m file, after the #import directives
static NSString* minecraftPath = @"~/Library/Application Support/minecraft/bin/";
- (IBAction)listArray:(id)sender
{
NSString* path = [minecraftPath stringByExpandingTildeInPath];
//you want to hang onto the array that is returned here, so you must retain it
//however, if you don't release the existing value, it will be leaked
[list release];
list = nil;
list = [[manager directoryContentsAtPath:pathFinal] retain];
[tableView reloadData];
}
- (void)dealloc
{
//because you retained it, you must release it
[list release];
[super dealloc];
}
更好的方法是将list
声明为属性并合成其访问者:
<强>·H 强>
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource> {
...
}
...
@property (retain) NSArray* list;
...
<强>的.m:强>
@implementation AppDelegate
@synthesize list;
...
然后您可以使用该属性并为您处理保留/释放:
- (IBAction)listArray:(id)sender
{
NSString* path = [minecraftPath stringByExpandingTildeInPath];
//you've set the property to use retain, so the synthesized accessor does that for you
self.list = [manager directoryContentsAtPath:pathFinal];
[tableView reloadData];
}
- (void)dealloc
{
//you still need to release when done
self.list = nil;
[super dealloc];
}