2011年1月16日日曜日

XcodeでMacRuby・6日目その2 NSTableView

いやーNSTableViewはきつかった。

- (int)numberOfRowsInTableView:(NSTableView*)tableView
 if (!xmlDocument) { 
  return 0;
 }
 // '/rss/channel/item/'の数を返します
 NSArray* nodes; 
 nodes = [xmlDocument nodesForXPath:@"/rss/channel/item" error:NULL]; 
 return [nodes count];
}
// NSTableViewデータソース - 
- (id)tableView:(NSTableView*)tableView objectValueForTableColumn:(NSTableColumn*)tableColumn row:(int)row
{
 if (!xmlDocument) { 
  return nil;
 }
 // テーブルカラムの識別子を取得します 
 id identifier;
 identifier = [tableColumn identifier];
 // 指定された行の、'/rss/channel/item'を取得します
 NSArray* nodes;
 NSXMLNode* node; 
 nodes = [xmlDocument nodesForXPath:@"/rss/channel/item" error:NULL]; 
 node = [nodes objectAtIndex:row];
 if ([identifier isEqual:@"title"]) { // 'title'の文字列を取得します
  nodes = [node nodesForXPath:@"title" error:NULL]; 
  if ([nodes count] == 1) {
   node = [nodes objectAtIndex:0]; 
   return [node stringValue];
  }
 }
 return nil;
}

// NSTableViewデリゲート
- (void)tableViewSelectionDidChange:(NSNotification*)notification
{
 // 選択された行を取得します
 int row; 
 row = [tableView selectedRow];
 // 選択された行の、'/rss/channel/item'を取得します
 NSArray* nodes;
 NSXMLNode* node; 
 nodes = [xmlDocument nodesForXPath:@"/rss/channel/item" error:NULL];
  node = [nodes objectAtIndex:row];
 // 'description'の文字列を取得します
 nodes = [node nodesForXPath:@"description" error:NULL]; 
 if ([nodes count] == 1) {
  NSString* description; 
  node = [nodes objectAtIndex:0]; 
  description = [node stringValue];
     // テキストビューに記事の内容を設定します 
     [textView setString:description];
 }
}
(void)windowControllerDidLoadNib:(NSWindowController *) aController
{
 // テーブルビューにデータを読み込みます 
 [_tableView reloadData];
 
}
実質3つの関数を書き換えるだけ、なんですが、わからないことだらけでした。
今回お世話になったのがデベロッパドキュメント中の
Developing Cocoa Applications Using MacRuby
この文書でした。NSTableViewを実際にMacRubyから使っているチュートリアル。

結局MacRuby版はこうなった。
def numberOfRowsInTableView(view)
  return 0 unless @xmlDocument
  
  nodes=@xmlDocument.nodesForXPath("/rss/channel/item",error:nil)
  nodes.count
 end
 
 def tableView(view,objectValueForTableColumn:column, row:index)
  return unless @xmlDocument
                    
  identifier=column.identifier
  
  nodes=@xmlDocument.nodesForXPath("/rss/channel/item",error:nil)
  node=nodes.objectAtIndex(index)
  
  if identifier.isEqual("title") then
   nodes=node.nodesForXPath("title",error:nil)
   if nodes.count==1 then
    node=nodes.objectAtIndex(0)
    return node.stringValue
   end
  end
  nil
 end

 def tableViewSelectionDidChange(notification)
  row=atableView.selectedRow
  nodes=@xmlDocument.nodesForXPath("/rss/channel/item",error:nil)
  node=nodes.objectAtIndex(row)
  
  nodes=node.nodesForXPath("description",error:nil)
  if nodes.count==1 then
   node=nodes.objectAtIndex(0)
   str=node.stringValue
   textView.setString str
  end
 
 end

セミナー用にわかりやすさを優先して書かれたソースだとは思うんですが、同じようなコードが並んでやや冗長か、と生意気に考えるおやぢ。
さっきamazonでcocoaの解説書を調べたら
たのしいCocoaプログラミング[Leopard対応版]
木下 誠
ビー・エヌ・エヌ新社
売り上げランキング: 20020

この本のレビューによるとやっぱりrssリーダーがお題になっているらしい。なるほど。

それはともかく、デリゲートってのは、Viewとかの更新を他のクラスにお任せしちゃうための機能、ということでいいのかな。

0 件のコメント:

コメントを投稿