Cocoa 如何向NSTableView中添加文件名的NSArray?-热可可
我需要帮助了解如何在NSTableView中显示NSArray的内容。我的NSArray中充满了(或者至少我认为是)目录中的文件名。我使用NSFileManager获取目录中文件的名称,然后将该信息加载到NSArray中。但我不知道如何将NSArray加载到NSTableView中 AppDelegate.hCocoa 如何向NSTableView中添加文件名的NSArray?-热可可,cocoa,nsarray,nstableview,Cocoa,Nsarray,Nstableview,我需要帮助了解如何在NSTableView中显示NSArray的内容。我的NSArray中充满了(或者至少我认为是)目录中的文件名。我使用NSFileManager获取目录中文件的名称,然后将该信息加载到NSArray中。但我不知道如何将NSArray加载到NSTableView中 AppDelegate.h #import <Cocoa/Cocoa.h> @interface AppDelegate : NSObject <NSApplicationDelegate>
#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
有两种方法可以做到这一点:在对象中使用或实现协议,并将该对象指定为表视图的
数据源
看起来您已经实现了一半的NSTableViewDataSource
方法。您需要将协议声明添加到接口中,以指示AppDelegate
对象实现协议:
@interface AppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource>
或者,可以通过将表视图的datasource
出口设置为AppDelegate
实例,在Interface Builder中分配数据源
但是,您遇到的主要问题是,您正在将一个自动删除的对象分配给列表
ivar,并且在重新加载表视图之前将其释放
您的listArray
方法有问题。没有理由将path
和pathfail
作为实例变量。它们只使用一次,因此应在本地确定范围。事实上,由于路径是一个常量,因此应该单独声明:
//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;
...
@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];
}
我很难让它工作。它什么也没做,我的日志里没有错误。当我加入NSTableDataSource协议时,它说找不到它,并告诉我将其更改为NSTableViewDataSource,我不知道这是否是问题所在。我将表设置为IB中的数据源和委托,但仍然没有发生任何事情。它还说directoryContentsAtPath已弃用。对不起,这是我对协议名称的错误,它是NSTableViewDataSource
。您没有将表视图设置为数据源,而是将AppController
对象设置为表视图的数据源。将表视图的datasource
出口连接到AppController
实例directoryContentsAtPath
已弃用。如果您查看文档,它会告诉您使用目录的内容atpath:error:
,所以请这样做。对不起,我犯了一个错误,我用错了。我确实将表视图的数据源连接到了AppController
。但是它仍然没有在表中显示任何内容,并且它说没有使用contentsOfDirectoryAtPath:error:
Use的实例方法。您需要阅读文档并正确使用该方法。我正按照他们所说的做,但现在它说没有内容的方法directoryatpath:error:
,并且它不断崩溃。来这里之前我想先看一下文件
@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];
}