• 締切済み

Objective-C, Cocoaアプリ

こんにちわ。初歩的な質問ですが、Objective-C, Cocoa Application両方とも初心者です。ボボタンを押すことで、NSTableViewに新しいデータを追加したいのですが、 デバッグして、データ自体はちゃんとデータソースの方に追加されているのですが、TableViewが表示していないようです。 reloadData, setNeedsDisplayも両方ためしたのですが、表示されません。 ちなみに、新しいデータを追加する関数ですが、tableViewがロードされる前にコールしたときはちゃんと新しいデータがtableViewに表示されています。 コードです。 ****************** dataはNSMutableArrayでItemInfoというクラスのArrayです。(ItemInfoは単純にNSString* nameとint priceの2つのデータを持っているクラスです。) この関数はすべてNSViewControllerのメンバ関数です。 -------コード---------- - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if(self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]){ data = [[NSMutableArray alloc]initWithCapacity:5]; [data addObject:[[ItemInfo alloc]initWithName:@"Item1" price:100]]; [self addNewItem:nil]; //ここでのaddNewItemは反映され、TableViewには合計2つのデータが表示されています。 } return self; } -(IBAction)addNewItem:(id)sender { //ここはボタンを押したときにちゃんと実行されているのを確認しています。 //実際にdataにも新しいデータが追加されていることをデバッガで確認済みです。 ItemInfo *newItem = [[ItemInfo alloc]initWithName:@"NewItem" price:300]; [data addObject: newItem]; [tableView reloadData]; } #pragma mark - #pragma mark Table View Datasource - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { return [data count]; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { //tableView には2つのColumnがあり、一つ目はItemInfo内のnameを、2つ目にはpriceを表示しています。 if([aTableColumn.identifier isEqual:@"Item"]){ return [[data objectAtIndex:rowIndex] name]; }else if([aTableColumn.identifier isEqual:@"Price"]){ return [NSString stringWithFormat:@"%d", [[data objectAtIndex:rowIndex] price]]; } return nil; } ------コード終わり------ 開発環境は以下の通りです。 OS: MacOSX10.6 SnowLeopard Xcode Version3.2.4 Cocoa Application

みんなの回答

  • harawo
  • ベストアンサー率58% (3742/6450)
回答No.1

例示のコードソースには、問題はないと見えます。 > //実際にdataにも新しいデータが追加されていることをデバッガで確認済みです。 (1) ItemInfoインスタンス「newItem」が、NSMutableArray「data」に追加されたことを確認した。 (2) ItemInfoインスタンス「newItem」に、「name = NewItem、price = 100」が保持(retain)されていることを確認した。 どちらでしょうか?本来なら、両方の確認でなければなりません。 例示のコードソースに問題がないのであれば、例示されていないクラス「ItemInfo」のコードソースを疑うことになります。 予測としてですが、ItemInfo内のデータ、nameとpriceが、autoreleaseされてしまっているのではないかと考えます。 ※本題と関係ありませんが、かついちいち指摘せずとも、おわかりのこととは存じますが、ねんのため。 > - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil NSTableViewをInterface Builderで作成している場合、「- (void)awakeFromNib」でテーブルまわりを初期化(Initialize)したほうが、確実です。 > data = [[NSMutableArray alloc]initWithCapacity:5]; たんに「[[NSMutableArray alloc] init]」でかまいません。これで初期化すると、「@""」つまり空の文字列が作成されます。ガベージコレクションが有効なObjective-C 2.0なら、「[NSString string]」でも可。 > return [NSString stringWithFormat:@"%d", [[data objectAtIndex:rowIndex] price]]; NSTableViewは、セルに渡すオブジェクトとして、NSStringだけでなく、NSNumberも使えるので、「[NSNumber numberWithInt: [[data objectAtIndex:rowIndex] price]]」でも可です。

関連するQ&A

  • iphoneでTableViewに動的追加できない

    UITableViewでWebから取得した情報を表示したく、非同期にCellを追加する テストアプリを書いていたのですが、わからない点がいくつかあります。 以下は非同期追加のテストコードで、実行するとリストに"foo"が一件だけ表示され 2秒おきにリストに”bar”が追加されます。 @interface AddRowTableViewController : UITableViewController { NSMutableArray *dataSouce; } -(void)onTimer:(NSTimer*)timer; @end @implementation AddRowTableViewController - (void)viewDidLoad { // 初期値は空欄 dataSouce = [[NSMutableArray alloc] init]; // (1) // 初期値としてfooを持つ //dataSouce = [[NSMutableArray alloc] initWithObjects:@"foo", nil]; // (1)' // 2秒ごとにbarを追加するためにインターバルタイマをセット [NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(onTimer:) userInfo:nil repeats:YES]; } // 2秒ごとに挿入のために呼ばれる -(void)onTimer:(NSTimer*)timer { // barを追加 [dataSouce addObject:@"bar"]; [self.tableView beginUpdates]; NSIndexPath* path = [NSIndexPath indexPathForRow:0 inSection:0]; // (2) [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationTop]; [self.tableView endUpdates]; // (3) [self.tableView reloadData]; // (4) } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [dataSouce count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *id = @"default-cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:id]; if(!cell){ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:id]; [cell autorelease]; } cell.textLabel.text = [dataSouce objectAtIndex:indexPath.row]; return cell; } #if 0 // (5) - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if([dataSouce count] > 0) return 1; else return 0; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { // テストなので、聞かれたらTitleと答えておく return @"title"; } #endif @end このプログラムは一応動作するのですが、少し変えると期待通りに動作しません。 疑問1 コード中の(1)をコメントアウト及び(1)’をコメントインした状態で、初期値として "foo"が画面に表示された状態からスタートするようになりますが、このとき (2)で先頭に挿入するように記載していますが、実際には2行目に挿入されます。 foo bar bar 例えば4秒後にはこんな感じに並びます。なぜでしょうか? 疑問2 (4)のコードを書くと挿入時にアニメーションしません。(4)のコードを書かないとbarではなく fooが追加されたように見えます。スクロールしてフレームアウト/インなどの動作が あるとセルがリロードされ正しくbarになります。 挿入アニメーションを有効にしつつ最新データを参照させるにはどうしたらよいのでしょうか? 疑問3 (5)を#if 1とすることでセクションが表示されるようになりますが、このときに 初期値として何かあれば追加できますが、初期状態が空欄の場合に追加できず (3)のコードがSIGABRTを発行してしまいます((1)だとNG、(1)’だと通る)。 空欄のセクション付きリストにCellを挿入するにはどうしたらよいでしょうか? 経験が浅く、非常識なコードになっているのではないかと思いますが、 どうにも自力ではこれ以上進めなくなってしまいました。 上記1~3の一つでもいいので、なにかヒントをいただけないでしょうか? 未検証のカンによるアドバイスも歓迎です、こちらで検証させて頂きます。 どうかよろしくお願い致します。

  • Objective-C for文でのインスタンス

    既出の質問と類似してますが、解決しないので質問します。 Objective-CのNSMutableArrayを使いラベルを複数個作りならべたいのですが、 変数iを使ってラベルに番号をつける方法がわかりません。 今のコードは NSMutableArray *tiles = [NSMutableArray array]; for( int i=0; i<25; i++ ){ UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0,0, tileSize,tileSize)]; label.text=[NSString stringWithFormat:@"%d",i]; [tiles addObject:label]; [self.view addSubview:label]; } です。 これを UILabel *label%d,i = [[UILabel alloc]initWithFrame:CGRectMake(0,0, tileSize,tileSize)]; のようにして、 label0、lable1、label2、label3・・・・ というように生成するにはどうしたらいいですか? Objective-C初心者です。 よろしくお願いします。

  • cocoa objective-c の return と * の意味がわかりません。

    objective-c の参考書を何冊か購入して 勉強しているのですが、本に載っていないようで ネットでもいくら探しても(探し方が悪いのか)行き当たらないので困ってしまいました。 先に進めなくなってしまいましたので教えていただきたく 投稿しました。 以下のコード(Project Builder起動直後のMyDocument.m)で return self; の return と - (NSString *)windowNibName の * です 使用法を教えていただけたら助かります。 よろしくお願いします。 #import "MyDocument.h" @implementation MyDocument - (id)init { self = [super init]; if (self) { message and return nil. } return self; } - (NSString *)windowNibName { return @"MyDocument"; } - (void)windowControllerDidLoadNib:(NSWindowController *) aController { [super windowControllerDidLoadNib:aController]; } - (NSData *)dataRepresentationOfType:(NSString *)aType { return nil; } - (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType { return YES; } @end

  • [objective-C]配列について

    はじめまして。 objective-C、cocos2dについての質問です。 iPhoneアプリを勉強しながら作り始めたのですが詰まってしまい、できればご助力をお願いしたいと思い質問させていただきました。 cocos2dというフレームワークを使用し簡単なRPGを作りたいと考えております。 そこでキャラクターのステータスを配列に格納し、どのシーンからも参照したいのですが、どうしてもうまくいきません。 別クラスでインスタンス変数を作り、それを利用して配列を作成する方法で実装しようとしており、実際のコードは以下の通りになります。 ---------------------------------- <Character.h> @interface Character : NSObject{ NSInteger characterStateAtk_; ・(Def、Hpなど) ・ } @property (nonatomic, assign) NSInteger characterStateAtk;  ・  ・ @end <Character.m> #import "Character.h" @implementation Character @synthesize characterStateAtk = characterStateAtk_;  ・  ・ @end キャラクターステータス生成部分 <CreateScene.h> @interface CreateScene : CCScene { NSMutableArray* characterStateArray_; } @property (nonatomic, assign) NSMutableArray *characterStateArray; @end <CreateScene.m> @interface CreateScene() - (void) pressReloadButton:(id)sender; - (void) createCharacterState; @end @implementation CreateScene @synthesize characterStateArray = characterStateArray_; - (void) dealloc{ [self.characterStateArray release]; [super dealloc]; } - (void) createCharacterState{ self.characterStateArray = [NSMutableArray array]; Character* priState = [[[Character alloc]init] autorelease]; priState.characterStateAtk = random() % 5 + 5; ・ ・ [self.characterStateArray addObject:priState]; } (その他の処理) - (void) pressReloadButton:(id)sender{ [self createCharacterState];  (ここでcharacterStateArrayを取得して表示したい) } ---------------------------------- 最初は、 NSInteger x; x = [[self.characterStateArray objectAtIndex:0]intValue]; で取得しようとしたのですがエラーとなり実行できませんでした。 (調べていくうちにobjective-Cでは配列の中身はオブジェクトしか使えないという事を知りました) プログラム中の(ここでcharacterStateArrayを取得して表示したい)の部分について、実装方法や考え方についてご助言をいただけないでしょうか? よろしくお願いいたします。

  • テーブルビューで配列が自動消滅することについて

    xcode4.1をつかってiphoneアプリを作成しています。 テーブルビューの画面遷移時に、 可変配列NSMutableArrayに plistを読み込ませたNSMutableDictionaryの一意のキーの中身を保存し、 更に選択した行番号で呼び出した配列の中身を別ビューに渡そうとすると失敗してしまいます。 ・・自動解放されてしまっていると思うのですが、 [[[NSMutableArray alloc] init] retain]; としてもうまくいきませんでした。 どうすればうまくデータを別ビューに渡せるでしょうか。 (plistの読み込みは必須です。。) すみませんがご教授いただけますでしょうか。。。 よろしくお願いいたします。 //-------- .h------ @interface DtlVCL : UITableViewController { //別のViewからデータ受け渡し用 NSString *rcvStr; //plist一時読み込み用 NSMutableDictionary *dic; NSMutableArray *ary; } .m------------ viewDidLoad------ //各変数初期化 ary = [[[NSMutableArray alloc] init] retain]; dic = [[[NSMutableDictionary alloc] init] retain]; id path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"xxxxxxxx.plist"]; if([[NSFileManager defaultManager] fileExistsAtPath:path] == YES){ dic = [NSMutableDictionary dictionaryWithContentsOfFile:path]; }else{ NSLog(@"Dtl :ファイル読み込みエラー"); } ary = [dic objectForKey:rcvStr];//rcvStrは前ビューから取得した文字列 ------------------- - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath------ ExpVCL *expvcl = [[ExpVCL alloc] initWithNibName:@"ExpVCL" bundle:nil]; //データの受け渡し expvcl.rcvNum = [indexPath row]; expvcl.rcvStr = [NSString stringWithFormat:@"%@",[ary objectAtIndex:[indexPath row]]]; [self.navigationController pushViewController:expvcl animated:YES]; [expvcl release];

  • iphoneアプリ開発での変数の受け渡し

    最近iPhoneアプリ開発を始めた者です。 変数の受け渡しについて質問があり、投稿させていただきました。 以下のコード内で、 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 以下で設定したIDに入ったデータを、 -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)senderの中のIDに受け渡したいのですが、どうやら2つのIDが繋がっていません。 自分自身あまりまだ理解できていないこともあり、ざっくりとした聞き方で申し訳ありません。 初歩的な質問だとは思うのですが、なにとぞご教授お願いします。 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 2; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil){ cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } if (indexPath.row == 0){ cell.textLabel.text = @"東京"; }else{ cell.textLabel.text = @"大阪"; } int ID = indexPath.row; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self performSegueWithIdentifier:@"mySegue" sender:self]; } -(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"mySegue"]) { SecondTableViewController *viewCon = segue.destinationViewController; viewCon.myValue = ID; } }

  • 【iOS】pickerViewを隠すには?

    pickerViewを、画面のどこかをタップすることで隠すには どのようにすればよろしいでしょうか。 現在のコードです。 TextFieldの代わりにピッカーを出すという実装です。 ヘッダー @property(nonatomic,weak)IBOutlet UITextField *textField; @property(nonatomic,strong)UIPickerView *pickerView; @property(nonatomic,strong)NSArray *items; メイン - (void)viewDidLoad { self.items = @[@"A",@"B",@"C",@"D"]; self.pickerView = [[UIPickerView alloc]init]; self.pickerView.dataSource = self; self.pickerView.delegate = self; self.pickerView.showsSelectionIndicator = YES; self.textField.inputView = self.pickerView; [super viewDidLoad]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{ return 1; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{ return [self.items count]; } - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ return [self.items objectAtIndex:row]; } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ self.textField.text = [self.items objectAtIndex:row]; } - (IBAction)pressHide:(id)sender{ [self.textField resignFirstResponder]; }

  • objective-c 描画処理について

    初心者ですが、iPhoneアプリを作成しています。 画像を並べてスクロールできるように配列で描画処理を行ないたいのですが、うまくいきません。 今のところのコードはこんな感じです↓ - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray* imageList = [NSMutableArray array]; for (int i=1; i < 20; i++) { UIImage* image = [UIImage imageNamed: [NSString stringWithFormat:@"%d.jpg", i+1]]; [imageList addObject:image]; } MyImageView* imageView = [[MyImageView alloc] initWithImage:imageList]; scrollView.contentSize = imageView.bounds.size; [scrollView addSubview:imageView]; [imageView release]; } どなたか分かる方、教えて頂けますよう宜しくお願いします。

  • TableViewでセル名が表示されない

    こんにちは。 iPhoneアプリの勉強している者ですが、TableViewControllerを使いセルごとに名前を表示させようとしているのですが、タイトルのみが表示されて肝心のセル名が表示されません。 appDelegate.mにてUINavigationControllerのインスタンス及びUITableViewControllerのインスタンスを作成してUITableViewControllerのインスタンスをrootViewControllerに設定しTableViewを表示させようとしています。 プログラムの記述のどこが間違っているのか教えて頂けると大変助かります。 以下UITableViewControllerのinterfaceセクションとimplementationセクションを掲載しますので、ご指摘お願いします。 #import <UIKit/UIKit.h> @interface SampleForSimpleTable : UITableViewController { NSArray *itemes; } @end @implementation SampleForSimpleTable - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; self.title = @"SimpleTable"; itemes = [[NSArray alloc] initWithObjects:@"ITME 1", @"ITEM 2", @"ITEM 3", @"ITEM 4", @"ITEM 5", @"ITEM 6", nil]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Potentially incomplete method implementation. // Return the number of sections. return 0; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete method implementation. // Return the number of rows in the section. return [itemes count]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *identifier = @"default-cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier ]; if (!cell){ cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; } cell.textLabel.text = [itemes objectAtIndex:indexPath.row]; // Configure the cell... return cell; }

  • [再]objective-c 描画処理について

    前回質問させて頂きましたが、まだ抜け出せていないので教えて下さい。 ↓↓↓ -------------------------------------------------------------------------------------------------------------- 初心者ですが、iPhoneアプリを作成しています。 画像を並べてスクロールできるように配列で描画処理を行ないたいのですが、うまくいきません。 今のところのコードはこんな感じです↓ - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray* imageList = [NSMutableArray array]; for (int i=1; i < 20; i++) { UIImage* image = [UIImage imageNamed: [NSString stringWithFormat:@"%d.jpg", i+1]]; [imageList addObject:image]; } MyImageView* imageView = [[MyImageView alloc] initWithImage:imageList]; scrollView.contentSize = imageView.bounds.size; [scrollView addSubview:imageView]; [imageView release]; } どなたか分かる方、教えて頂けますよう宜しくお願いします。 -------------------------------------------------------------------------------------------------------------- ↓ NSArray *initWithImage;と引数で渡しましたが、 「MyImageView* imageView = [[MyImageView alloc] initWithImage:imageList];」 の部分で、「Incompatible pointer sending 'NSMutableArray *' to parameter of type 'UIImage *'」とエラー表示され、実行すると、 「Tread1 : Program received signal: "SIGABRT"」で落ちてしまいます。

専門家に質問してみよう