ヒレガス本 第5章 ヘルパ・オブジェクト

jitte2007-04-14


まさかナイトライダーロボコップが引用されるとは。
内容はTableViewの基本的な使いかたとかキー・バリュー・コーディングの話とか。セミナーのほうがよっぽど複雑だったので今回は余裕。

練習問題1

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
{
	[deleteButton setEnabled: ([tableView selectedRow] != -1 && [employees count] > 1)];
}

練習問題2

- (IBAction)deleteEmployee: (id)sender
{
	NSArray *a = [[tableView selectedRowEnumerator] allObjects];
	
	int i;
	for (i = [a count] - 1; i >= 0; i--) {
		[employees removeObjectAtIndex: [[a objectAtIndex: i] intValue]];
	}
	[self updateUI];
}

追記:RubyCocoa版。

  • valueForKeyは動くのにsetValue_forKeyがダメだった。
  • KVCのためには、kvc_accessorでインスタンス変数を宣言しておけばよい。
  • Person#unableToSetNilForKeyは呼ばれないが、理由はRuby側では変数に型がないので「Floatにnilをセットできない」例外は発生しないため。意図的に発生したいときはどうするのか疑問だけどまあ今は追求する必要はなかろう。
require 'osx/cocoa'
include OSX

class MyDocument < NSDocument
  ib_outlet :deleteButton, :tableView
  def initialize
	@employees = [];
	createNewEmployee
  end
  def createNewEmployee
	@employees.push Person.alloc.init
  end
  def newEmployee(sender)
	createNewEmployee
	updateUI
  end
  def deleteEmployee(sender)
	a = @tableView.selectedRowEnumerator.allObjects
	(a.count).downto(1) do |i|
		@employees.delete_at(a.objectAtIndex(i - 1).intValue)
	end
	updateUI
  end
  def updateUI
	@tableView.reloadData
	@deleteButton.setEnabled(@tableView.selectedRow != -1 && @employees.size > 1)
  end
  def numberOfRowsInTableView(aTableView)
	@employees.size
  end
  def tableView_objectValueForTableColumn_row(aTableView, aTableColumn, rowIndex)
	identifier = aTableColumn.identifier
	person = @employees[rowIndex]
	person.valueForKey(identifier)
  end
  def tableView_setObjectValue_forTableColumn_row(aTableView, anObject, aTableColumn, rowIndex)
	identifier = aTableColumn.identifier
	person = @employees[rowIndex]
	person.setValue_forKey(anObject, identifier)
  end
  def tableViewSelectionDidChange(aNotification)
	@deleteButton.setEnabled(@tableView.selectedRow != -1 && @employees.size > 1)
  end

  ns_overrides 'windowNibName', 'windowControllerDidLoadNib:',
    'dataRepresentationOfType:', 'loadDataRepresentation:ofType:'

  def windowNibName
    return "MyDocument"
  end
  def windowControllerDidLoadNib (aController)
    super_windowControllerDidLoadNib(aController)
	updateUI
  end
  def dataRepresentationOfType (aType)
    return nil
  end
  def loadDataRepresentation_ofType (data, aType)
    return true
  end
  def dealloc
	super
  end
end

class Person < NSObject
	kvc_accessor :personName, :expectedRaise

	def initialize
		@personName = "NewEmployee"
		@expectedRaise = 0.0
	end
	def unableToSetNilForKey(key)
		puts "unableToSetNilForKey"
		if key.to_s == "expectedRaise"
			@expectedRaise = 0.0
		else
			super
		end
	end
	def dealloc
		NSLog("Dealocing %@", @person_name)
		super
	end
end