PDA

View Full Version : Key-Value Coding and Encapsulation




MacRohde
Jun 26, 2007, 03:01 PM
I'm trying to get into the Mac programming platform and therefore I'm in the middle of learning some Cocoa and Objective-C.

I've read that instance variables are private by default, and the convention is to use accessors of the form:

-(Type)property;
-(void)setProperty(Type *):aType;

That's all fine and dandy.

Then I read about key-value coding and that seems cool and all, but apparently if the accesssor does not exist key-value coding simply accesses the instance variable directly!

That blows a big hole in the "encapsulation wall". If I didn't supply an accessors it's because I don't want anyone peaking at my internals (well, my class' internals).

Maybe I missed something....???



HiRez
Jun 26, 2007, 03:12 PM
Then I read about key-value coding and that seems cool and all, but apparently if the accesssor does not exist key-value coding simply accesses the instance variable directly!

That blows a big hole in the "encapsulation wall". If I didn't supply an accessors it's because I don't want anyone peaking at my internals (well, my class' internals).

Maybe I missed something....???I think if you use the @private keyword on the variables you don't want to be accessed, maybe they won't be by the KVC system? I really don't know though, that's just speculation on my part. Seems like it should work that way. Maybe it would then throw some sort of access exception or something.

Nutter
Jun 26, 2007, 05:22 PM
KVC does access private instance variables directly if necessary. There is no way to stop it from doing so.

I wouldn't consider this a serious breach of encapsulation. When no accessors are present, the KVC system essentially simulates very basic accessors for you. If you decide at a later stage that this isn't sufficient, you can add custom accessor methods. The user of the object doesn't need to know or care whether KVC is using accessor methods or accessing the variable directly. So, from a functional point of view the separation of interface and implementation is preserved.

I would still strongly recommend using accessors (or Objective-C 2 properties) for all variables that you expect to access with KVC. The main reason for doing so in cases where there is no functional necessity is simply to document the difference between properties which are meant to be available to other objects and truly private instance variables.

It's purely convention which dictates that you shouldn't access an object's instance variables unless accessors are provided. This convention holds true with KVC even though Apple's implementation doesn't enforce it. There's nothing stopping you from accessing instance variables with object->ivar either, but convention tells you that it's not a good idea.

kainjow
Jun 26, 2007, 06:06 PM
There's nothing stopping you from accessing instance variables with object->ivar either, but convention tells you that it's not a good idea.

I get compiler errors when I do that.

Without KVC, you can still write a category method to access private ivars. Unless you're writing DRM code or serial number validation, don't worry about it.

Nutter
Jun 26, 2007, 06:44 PM
Hmm. I seem to remember reading on cocoadev.com that using -> to access ivars was possible. I never bothered to try it...

kainjow
Jun 26, 2007, 06:48 PM
Hmm. I seem to remember reading on cocoadev.com that using -> to access ivars was possible. I never bothered to try it...

It used to work for me, but recently when I've tried it, it doesn't. Maybe it's a compiler switch, or maybe they changed it with a recent GCC update. I don't know.