Closed jordanmaguire closed 11 years ago
This is because the accessor of nanostore models are actually stored in the 'info' ductionary, not real properties. Perhaps you can try to use KVO on 'info' for dictionary change instead.
It seems like you can't use KVO on hashes/dictionaries.
ie:
modelInstance.info = {} # invokes kvo
modelInstance.info["ilovekvo"] = "something" # doesn't invoke KVO
modelInstance.info = "beans" # invokes kvo
So I tried manually calling the KVO in lib/nano_store/model.rb
like so:
def attribute(name)
attributes << name
define_method(name) do |*args, &block|
self.info[name]
end
define_method((name + "=").to_sym) do |*args, &block|
self.willChangeValueForKey(name) # here doesn't go bang
self.info[name] = args[0]
self.didChangeValueForKey(name) # here goes bang
end
end
but RubyMotion goes bang with:
Method `id' created by attr_reader/writer or define_method cannot be called from Objective-C. Please define manually the method instead.
I can't continue looking tonight so I might have another crack tomorrow.
Here's a quick and dirty setup I've been testing in:
class Radio < NanoStore::Model
attribute :id
end
class RadioObserver
def self.test
ro = RadioObserver.new
ro.startObserving
ro.radio.id = "Jordan"
end
def radio
@radio ||= Radio.new
end
def startObserving
radio.addObserver(self, forKeyPath:"info", options: NSKeyValueObservingOptionNew, context: nil)
radio.addObserver(self, forKeyPath:"id", options: NSKeyValueObservingOptionNew, context: nil)
end
###
# NSKeyValueObserving
# http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOBasics.html
###
# This method is invoked by the system when an observed instance is changed
def observeValueForKeyPath(keyPath, ofObject:object, change:change, context:context)
puts "keyPath: #{keyPath}"
end
end
@jordanmaguire have you solved the Method 'id' created by attr_reader/writer or define_method cannot be called from Objective-C. Please define manually the method instead.
problem?
Yo @bogardon, I didn't. I ended up having to change the implementation anyway so I had no need to use the KVO on the attributes.
Sorry for late reply, I found a way to listen to the change of a key from NSMutableDictionary:
radio.addObserver(self, forKeyPath:"info.id", options: NSKeyValueObservingOptionNew, context: nil)
That should work without modifying model class.
For the Method 'id' created by attr_reader/writer or define_method cannot be called from Objective-C.
error, i have no idea... we'll need consult rubymotion team. Meanwhile, I'll closing the issue.
Another workaround:
class Radio < NanoStore::Model
attribute :id
def id
self.info[:id]
end
end
... yeah that's sucks. :-/
Hey,
I haven't been able to get KVO working using attributes defined on a NanoStore::Model.
If I replace the attribute with an attr_accessor KVO starts working so I don't think I'm doing anything wrong initializing the KVO. EG:
Any idea how it is possible to fix this? My code would be much cleaner if I were able to use KVO on my model attributes.
nano-store version is 0.6.0
Let me know if you need any further information.
Thanks