Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > valueForKey method?

valueForKey method?
Thread Tools
Fresh-Faced Recruit
Join Date: Sep 2000
Status: Offline
Reply With Quote
Jun 11, 2001, 08:13 AM
 
In the learning Cocoa book, there is an example which uses a method called valueForKey to get the value of a member variable from a pretty simple class. By simple, I eman the class just inherits from the Object class, and has 3 data members, as well as getter/setter functions for those member variables. I have a few questions about this method:

The method call looks like this...
<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>
NSString* variableName; <font color = brown>// This is set to the name of a variable in the class</font>

[target valueForKey: variableName]
</font>[/code]

So, say I have a date member variable in my target class, I can call [target valueForKey: @"date"] and have it return the date for me. Now, does the valueForKey method actually get the member variable, or does it return the return value of the getter function of the same name? Does the call have to match the NSString variableName to the getter or the member variable? This is confusing to me since the getter and the member variable share the same name in the examples, and by convention.

Do all classes that derive from NSObject have this function? If so, why must we always implement getters, rather than call this? Overhead?

All in all, this book is helping me, but providing me with as many new questions as answers, it seems like. Coverage could be deeper.

Luckily, I have you guys to ask! Thanks for helping!

Spencer
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
Jun 11, 2001, 12:13 PM
 
Originally posted by swcrissman:
<STRONG>So, say I have a date member variable in my target class, I can call [target valueForKey: @"date"] and have it return the date for me. Now, does the valueForKey method actually get the member variable, or does it return the return value of the getter function of the same name?
</STRONG>
valueForKey: first looks for a method by that name, and if it's not there, looks for the instance variable of that name. So, if you have a method, it will be called. [If a class overrides +accessInstanceVariablesDirectly to return NO, then valueForKey: will not look for instance variables in objects of that class. I don't think any existing classes override this though.]

The methods are declared in NSKeyValueCoding.h, and are documented in /System/Library/Frameworks/Foundation.framework/Resources/English.lproj/Documentation/Reference/ObjC_classic/Protocols/NSKeyValueCoding.html

<STRONG>
Do all classes that derive from NSObject have this function? If so, why must we always implement getters, rather than call this? Overhead?
</STRONG>
Yes, the methods are implemented on NSObject, so all classes that inherit from NSObject have it (which is so say basically every object).

The key value coding methods are more intended to be used by generic, abstract code that doesn't know what kind of classes it's dealing with in advance -- valueForKey: offers a way for code to call methods on a class when it doesn't know what the class' methods. It can open up the door for some powerful abstractions, but isn't really intended for run-of-the-mill code.

If you're writing code where you already know which classes we're dealing with, it makes much more sense to use the provided API. When using valueForKey:, the compiler can do no type-checking. If you misspell the string, you won't find out until runtime, rather than having the compiler catch it for you. If the method returns an NSDate but you accidentally assign it to an NSString variable, the compiler won't be able to catch it, and again you'll be left to find out at runtime when your code tries to call an NSString method on the value. And while valueForKey: is pretty fast, it's definitely not as fast as calling the method directly. In short, you'd be losing a staggering amount of compile-time type checking plus some performance by using valueForKey: everywhere, where the only benefit is not having to write a few accessor methods. While it would work, it's not worth it.

For an example of where valueForKey: is useful, you could look at MiscMergeKit, currently distributed with my autodoc tool (www.misckit.com). It can read in a text template, with certain sections specially marked as "keys". When executed, an object (any object) is provided at runtime, and the marked sections are replaced with the -valueForKey: for the string. For example, "Dear &lt;&lt;fullName&gt;&gt;: In case you have forgotten your password, the password hint you originally provided is &lt;&lt;passwordHint&gt;&gt;. If you still can't remember your password, ...". At runtime, the -fullName and -passwordHint method will be called on the provided object, and the returned values placed in the final result. [Actually, -valueForKeyPath: is used, where a key like "foo.bar.baz" is turned into successive -valueForKey calls. MiscMerge also has looping constructs and other stuff.]

Before -valueForKey:, MiscMerge required the use of dictionaries rather than working on any object. To use it, the coder had to build up dictionaries with all values needed by the template. With -valueForKey:, the original objects -- no matter which class -- can just be used directly, and have its methods directly called. Autodoc uses it to produce class documentation -- it parses ObjC code and stores the data into some internal objects, then it runs those objects through a template to produce the documentation (different doc formats are supported by using different templates).

Apple uses -valueForKey: in a similar situation; to help with AppleScript support in the Cocoa frameworks. Much of the EOF and WebObjects products are also based around it; most of the abstractions and functionality they provide would not have been possible without it.
     
Fresh-Faced Recruit
Join Date: Sep 2000
Status: Offline
Reply With Quote
Jun 11, 2001, 01:57 PM
 
Thanks lindberg, that was really informative! Everything I was looking for and then some. The example is very interesting as well. I wasnt actually proposing using valueForKey all the time, just wondering what drawbacks would be attached if such a thing were tried. You answered that perfectly. Again, much thanks.

Spencer
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 09:50 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2