I'm not familiar with the Ruby observer mechanism you refer to - could you post 
a link?

Matt

On Nov 29, 2010, at 6:34 AM, Alan Skipp wrote:

> I hope people don't mind me posting this bit of code to the list, but I hope 
> it will be of some use to others and would also be interested to hear if the 
> technique has any problems which I've not foreseen.
> 
> Ruby has its own means of implementing the observer pattern, but as Key Value 
> Observing (KVO) is so pervasive in cocoa, it would be good if it was easy to 
> use. The module is an attempt at making KVO a bit more pleasant to use in 
> macruby. 
> The ideas have been adapted/stolen from here:
> 
> https://gist.github.com/153676
> 
> The following is an example of how to have a block of code executed 
> asynchronously every time a property of an instance variable changes
> 
> self.add_observer_for_key_path('person.first_name', async:true) do 
> |object,change|
>     object.do_expensive_calculation #will not block main thread
> end
> 
> A concern I do have is that the object which wants to receive KVO 
> notifications holds an array of Observer objects. These Observer objects hold 
> a reference to the object receiving the KVO notifications. Is this going to 
> cause havoc with garbage collection?
>  
> module KVO
> 
>   class Observer
>     require 'dispatch'
> 
>     attr_reader :observee, :path
>     def initialize(object, path, async, block, opts=0)
>       @observee = object
>       @path = path
>       @async = async
>       @block = block            
>       @observee.addObserver(self, forKeyPath:path, options:opts, context:nil)
>     end
> 
>     def observeValueForKeyPath(path, ofObject:object, change:change, 
> context:context)
>       if @async
>         Dispatch::Job.new { @block.call(object, change) } 
>       else
>         @block.call(object, change) 
>       end
>     end
> 
>     def cancel_observation
>       @observee.removeObserver(self, forKeyPath:@path)
>     end
>   end
> 
>   def add_observer_for_key_path(path, async:async, &block)
>     (@_observers_array_ ||= []) << Observer.new(self, path, async, block)
>   end
> 
>   def add_observer_for_key_path(path, async:async, options:opts, &block)
>     (@_observers_array_ ||= []) << Observer.new(self, path, async, block, 
> opts)
>   end
> 
>   def remove_observer_for_key_path(path)
>     observer = @_observers_array_.find {|o| o.path == path && o.observee == 
> self} if @_observers_array_
>     @_observers_array_.delete(observer) and observer.cancel_observation if 
> observer
>   end
>   
> end
> _______________________________________________
> MacRuby-devel mailing list
> MacRuby-devel@lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to