• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bindings - registering change notification for multiple keys
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bindings - registering change notification for multiple keys


  • Subject: Re: Bindings - registering change notification for multiple keys
  • From: Ken Thomases <email@hidden>
  • Date: Wed, 2 Jul 2008 06:14:57 -0500

On Jul 2, 2008, at 5:12 AM, dreamcat7 wrote:

Thank you for all of your comments Ken, very helpful.

You're welcome.


On 2 Jul 2008, at 09:16, Ken Thomases wrote:
custom class (say, "Preferences") -- again, making the dictionary an implementation detail -- and making the keys into properties of the Preferences class. In either case, there should be not key path which directly accesses the NSMutableDictionary without going through a custom setter of your own making

Yes that's good advice - it would be better to make a Preferences object that handled all of the preferences data, and also the saving and loading operations. Then obj-c properties for the accessor methods. Thank you for pointing out these missing KVO/KVC functionalities of NSMutableDictionary. I shall be sure not to use it except for plist back-end.

See my other message. Turns out I was wrong about NSMutableDictionary and KVO. :(



If you really need for there to be a dynamic set of properties, you can accomplish that using valueForUndefinedKey: and setValue:forUndefinedKey:. Basically, you have "virtual" properties -- they won't have proper individual accessors, but the above-named methods will be invoked whenever anything tries to access them via KVC, and in your implementations you can simulate their existence (by accessing the NSMutableDictionary which is part of your implementation, for example)

If i understand correctly what you say its actually possible to override that function for plist-type object ?

You override it in your custom class, e.g. Preferences, which is not a plist-type object.


- setValue:(NSObject*) obj ForUndefinedKey: (NSString*) key
{
// If i have an internal representation of NSMutableDictionary for the .plist file
[self.myMutableDict_PlistStore setValue:obj ForKey: key];

Yes, this implementation is what I would expect (modulo the case of "forKey:"), although you might want to use NSMutableDictionary's setObject:forKey: because its setValue:forKey: has some potentially dangerous smarts about keys with periods in them.


// If property Key is written with a naming convention, e.g. prefixed with letters 'PTUI'
// We may might assume it is one of our UI Element keys. And we may include a handler for this weak type.

Didn't really follow that.

// We can to call our data store-class methods to implement the common repetitive functionality**
// e.g. [self savePlistStore]; or we cache the PlistStore and save it when application becomes idle.**

Yeah, you can set a dirty flag and/or queue an idle-time notification (see NSNotificationQueue and NSPostWhenIdle).


}

So to confirm it will be triggered whenever any other object tries to access or save an undeclared property ?
Its also likely that elsewhere in the code accessing these non- existent properties give rise to some compiler warnings (!! ).

The undefined-key methods are only triggered when something uses KVC to set a property. If you're getting compiler warnings, then you're not using KVC, and you'll get errors.


That's an important consideration with this approach. Since you're going totally dynamic with KVC, you lose a variety of compiler checking on what you're doing. A typo in a key or key path string could result in a hard-to-notice bug.

If you have code somewhere which is currently using real accessors, and which after a switch to this scheme would be hard-coding key names, then that suggests you have some "real" properties which are known in advance. In that case, I recommend creating normal properties rather than relying on this undefined key mechanism. A _lot_ of the tedium of implementing such properties is eliminated by Objective-C 2.0's @property feature.


However for a more complex UI and many IB controls / outlets it means fewer (1) places to repeat that complexity on the model-side.
Certain larger cocoa apps - could benefit by using this approach.

Again, my suggestion was for cases where you truly need run-time dynamism in the set of properties supported by an object. Plenty of large Cocoa apps work just fine without going to this extreme. There are plenty of mechanisms for eliminating this complexity.


From what you've said about maintainability, you seem to think that having real properties will present a maintainability problem. I suspect you've got that backwards. I suspect that going with full dynamism when you don't have to will result in a maintainability problem.

** and in real-world application i no longer need to wire all controls to target action "uiSateState". Then binding to the undefined key 'PTUI(ElementName)' is neater.

Again, didn't follow that. It seems you're carrying on a side conversation with someone else, maybe?


It is weak-typing, but allows dynamic UI elements. And more coherent - looking code. This [self savePlistStore] is equivalent to synthetic property anyPreferences ( which Ken describe also for dependantKeys method below).

Well, not quite equivalent. I think what you're saying is that using the setValue:forUndefinedKey: gives you an opportunity to save your model, and therefore you don't need to have an observer watching for changes to properties of the model, if that observer were only doing so in order to save the model. So, while I disagree that savePlistStore is "equivalent" to anyPreferences, I can see how setValue:forUndefinedKey: would obviate the need for observing anyPreferences.


In the case of a static set of properties, the best thing to do is implement +keyPathsForValuesAffectingAnyPreferences in the Preferences class and return a set of the names of all of those properties:

+keyPathsForValuesAffectingAnyPreferences
{
return [NSSet setWithObjects:@"debug", /* list the other preference names here... */, nil];

If i declared my properties in the Preferences class, maybe there's a way to dump those list in obj-c from the class object and use it here.

I was suggesting that +keyPathsForValuesAffectingAnyPreferences be implemented on the Preferences class, in the case where you have a static set of properties. It doesn't seem reasonable to me that the Preferences class would want to consult the Objective-C runtime to learn its own properties. It should already know them! That's part of the responsibilities of a class.


Again, it seems to me that you're taking dynamism to an unreasonable extreme.

If not then it might be a workaround to subclass the NSObject class to find the list of properties that belong to it.

If you use the Objective-C 2.0 "declared property" (@property) feature, it does provide property introspection if you insist on going that route. Remember, though, that you don't want the "anyPreferences" property to depend on _every_ property of the class, because that would make it dependent on itself. Even beyond the issue of making a property depend on itself, I suspect you'll find that the Preferences class has several properties which should not affect "anyPreferences" -- for example, if the Preferences class maintains a reference to its store by file path. So, I think you will always want to state explicitly in code the list of key paths on which "anyPreferences" depends. Doing otherwise opens you up to unintended consequences in the future.


Also remember that, if you implement "virtual" properties using the undefined-key methods, then there's no such thing as "the list of properties for this class". With that much dynamism, then each _instance_ has its own set of properties which can change at will.

Cheers,
Ken
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Bindings - registering change notification for multiple keys
      • From: dreamcat7 <email@hidden>
References: 
 >Bindings - registering change notification for multiple keys (From: dreamcat7 <email@hidden>)
 >Re: Bindings - registering change notification for multiple keys (From: Ken Thomases <email@hidden>)
 >Re: Bindings - registering change notification for multiple keys (From: dreamcat7 <email@hidden>)

  • Prev by Date: Re: Bindings - registering change notification for multiple keys
  • Next by Date: Re: KVO Bug With Keypaths
  • Previous by thread: Re: Bindings - registering change notification for multiple keys
  • Next by thread: Re: Bindings - registering change notification for multiple keys
  • Index(es):
    • Date
    • Thread