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