These changes let you write methods for KVO accessing using natural Ruby syntax: class T kvo_array :squares do def size 10 end def [](i) i * i end end end
T.new.valueForKey('squares') => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
--- lib/hotcocoa.rb | 1 + lib/hotcocoa/kvo_accessors.rb | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 0 deletions(-) create mode 100644 lib/hotcocoa/kvo_accessors.rb diff --git a/lib/hotcocoa.rb b/lib/hotcocoa.rb index 4ca61f0..8b294e9 100644 --- a/lib/hotcocoa.rb +++ b/lib/hotcocoa.rb @@ -17,5 +17,6 @@ require 'hotcocoa/data_sources/table_data_source' require 'hotcocoa/data_sources/combo_box_data_source' require 'hotcocoa/kernel_ext' require 'hotcocoa/plist' +require 'hotcocoa/kvo_accessors' HotCocoa::Mappings.reload diff --git a/lib/hotcocoa/kvo_accessors.rb b/lib/hotcocoa/ kvo_accessors.rb new file mode 100644 index 0000000..1ecacdb --- /dev/null +++ b/lib/hotcocoa/kvo_accessors.rb @@ -0,0 +1,33 @@ +class Object + + def self.kvo_array(key, &b) + capitalized_key = key.to_s.capitalize + signatures = {:size => { selector: :"countOf#{capitalized_key}", type_signature: "i@:", flip: false }, + :[] => { selector: :"objectIn#{capitalized_key}AtIndex:", type_signature: "@@:i", flip: false }, + :insert => { selector: :"insertObject:in#{capitalized_key}AtIndex:", type_signature: "v@:@i", flip: true }, + :delete_at => { selector: :"removeObjectFrom#{capitalized_key}AtIndex:", type_signature: "v@:i", flip: false } + } + + c = Module.new + c.module_eval &b + c.instance_methods.each do |m| + signature = signatures[m] + if signature + method = c.instance_method(m) + if signature[:flip] + method = Proc.new { |a, b| method.bind(self).call(b, a)} + end + c.send(:define_method, signature[:selector], method) + c.send(:remove_method, m) + c.method_signature(signature[:selector], signature[:type_signature]) + + elsif not Module.instance_methods.include?(m) + raise ArgumentError, "Method `#{m}' isn't a KVO array accessor" + end + + end + + include c + end + +end -- 1.6.0.2