これは典型的な質問であることは知っています。これについて話している多くのスレッドを見つけましたが、実装のどこに問題があるのか 本当にわかりません。すべてをセットアップし、NSTableView 内の NSMutableArray にロードされたデータを確認できます。問題はそのデータを変更することです。私がすることは:
-(void) setData:(NSMutableArray*)data{
for (int i=0; i<[data count]; i++){
[list addObject:[data objectAtIndex:i]];
}
[self reloadData];
}
メソッドが
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
[self reloadData] の後に (予想どおり) 呼び出されていましたが、そうではありません。
明確にするために、「setData」は、NSTableView を拡張し、NSTableViewDataSource も実装する TableViewController 内に配置されます。インターフェイスに表示された実際の NSTableView を参照するため、「自己」は正しいはずです。
編集
以下は、TableViewController.m のコードです。
#import "TableViewController.h"
#import "Transaction.h"
@implementation TableViewController
- (id) init
{
self = [super init];
if (self){
list = [self loadData];
//list = [[NSMutableArray alloc]init];
}
NSLog(@"init");
return self;
}
-(void) setData:(NSMutableArray*)data{
NSLog(@"setData");
[list removeAllObjects];
for (int i=0; i<[data count]; i++){
[list addObject:[data objectAtIndex:i]];
}
[self reloadData];
}
-(void)reloadData{
NSLog(@"reloadData. List: %ld",[list count]);
[super reloadData];
}
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView{
return [list count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSLog(@"tableView");
Transaction *t = [list objectAtIndex:row];
if ([[tableColumn identifier] isEqualToString:@"date"]){
[[tableColumn headerCell] setTitle:@"Date"];
return [t date];
}
if ([[tableColumn identifier] isEqualToString:@"type"]){
[[tableColumn headerCell] setTitle:@"Type"];
return [t type];
}
if ([[tableColumn identifier] isEqualToString:@"category"]){
[[tableColumn headerCell] setTitle:@"Category"];
return [t category];
}
if ([[tableColumn identifier] isEqualToString:@"amount"]){
[[tableColumn headerCell] setTitle:@"Amount"];
return [NSString stringWithFormat:@"%f",[t amount]];
}
return @"//";
}
-(NSMutableArray *)loadData{
LoadSave* ls = [LoadSave alloc];
NSMutableArray* array = [[ls loadDataFromDisk] wallet];
for (Transaction* t in array){
//NSLog([t toString]);
}
// Load 1 row just to see if I can update the table later with more data
Transaction *t = [array objectAtIndex:1];
NSMutableArray * test = [NSMutableArray arrayWithObject:t];
return test;
}
@終わり
ヘッダ:
#import <Foundation/Foundation.h>
#import "Wallet.h"
#import "LoadSave.h"
@interface TableViewController : NSTableView <NSTableViewDataSource,NSTableViewDelegate> {
NSMutableArray *list;
}
-(void) setData:(NSMutableArray*)data;
-(IBAction)test:(id)sender;
- (id) initWithData:(NSMutableArray*)data;
@end
そして、これは今のところ私の AppDelegate です:
#import "AppDelegate.h"
#import "Transaction.h"
#import "TableViewController.h"
@implementation AppDelegate
@synthesize tableView;
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
LoadSave* ls = [LoadSave alloc];
Wallet *wallet = [ls loadDataFromDisk];
tableView = [[TableViewController alloc]init];
[tableView setData: wallet.wallet ];
}
-(IBAction)test:(id)sender{
LoadSave* ls = [LoadSave alloc];
Wallet *wallet = [ls loadDataFromDisk];
[tableView setData: wallet.wallet ];
}
@end
ご覧のとおり、アプリの起動が完了したときとインターフェイスのボタンを使用して、新しいデータをロードしようとしています。しかし、何も起こりません。
編集2:
tableView がコントローラー クラスのインスタンスであることがわかるように、これは AppDelegate のヘッダーです。
#import <Cocoa/Cocoa.h>
#import "TableViewController.h"
#import "LoadSave.h"
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
@property IBOutlet TableViewController *tableView;
-(IBAction)test:(id)sender;
@end
これは SaveLoad.m です。これは、任意のファイルからデータを保存、読み込み、インポートするために使用するものです。
#import "LoadSave.h"
@implementation LoadSave
NSString *const PATH = @"file.csv";
- (NSString *) pathForDataFile
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *folder = @".";
folder = [folder stringByExpandingTildeInPath];
if ([fileManager fileExistsAtPath:folder] == NO)
{
[fileManager createDirectoryAtPath:folder withIntermediateDirectories:NO attributes:nil error:nil];
}
NSString *fileName = @"wallet.data";
return [folder stringByAppendingPathComponent: fileName];
}
- (void)saveDataToDisk:(id)wallet
{
NSString * path = [self pathForDataFile];
NSMutableDictionary *rootObject;
rootObject = [NSMutableDictionary dictionary];
[rootObject setValue:wallet forKey:@"wallet"];
[NSKeyedArchiver archiveRootObject:rootObject toFile: path];
}
-(Wallet*)loadDataFromDisk
{
NSDictionary* root = [NSKeyedUnarchiver unarchiveObjectWithFile:[self pathForDataFile]];
return [root valueForKey:@"wallet"];
}
-(NSMutableArray*) importDataFromCSV
{
NSString* contents = [NSString stringWithContentsOfFile:PATH
encoding:NSUTF8StringEncoding
error:nil];
NSArray* lines = [contents componentsSeparatedByString:@"\n"];
NSRange range;
range.location = 1;
range.length = [lines count]-1;
lines = [lines subarrayWithRange:range];
NSMutableArray *data = [[NSMutableArray alloc] init];
for (NSString* line in lines)
{
NSArray* fields = [line componentsSeparatedByString:@","];
Transaction *t = [[Transaction alloc] init:fields[0] transactionType:fields[1] transactionCategory:fields[3] transactionAmount:fields[6]];
[data addObject:t];
}
// wallet* wallet = [Wallet alloc];
// wallet.wallet = data;
// LoadSave *ls = [LoadSave alloc];
// [ls saveDataToDisk:wallet];
return data;
}
@end
メソッドを静的なように使用しているため、initなしのallocはまだ機能していると思いますが、これまで静的にする方法を検索していなかったので、そのままにしておきました。
インターフェイスを説明する代わりに、その写真を投稿する方が簡単だと思います..
ただし、この時点では..プロジェクト全体をここに投稿することもできましたxD