Pages

Saturday, April 3, 2010

Key-Value Coding (KVC) in Cocoa

Key-Value Coding - directly set or get a property of an object by the property name - the key.
#import <Foundation/Foundation.h>

@interface Person : NSObject
{
NSString* firstName;
NSString* lastName;
}

@end

@implementation Person

- (id)init
{
[super init];
firstName = [[NSString alloc] init];
lastName = [[NSString alloc] init];
return self;
}

- (void)dealloc
{
[firstName release];
[lastName release];
[super dealloc];
}

@end

int main()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Person* person = [[Person alloc] init];

[person setValue:@"Pavel" forKey:@"firstName"];
[person setValue:@"Gnatyuk" forKey:@"lastName"];

NSLog(@"Name: %@", [person valueForKey:@"firstName"]);
NSLog(@"Last Name: %@", [person valueForKey:@"lastName"]);

[person release];
[pool drain];
return 0;
}
Mac OS X Reference Library. Key-Value Coding Fundamentals
Cocoa with Love. 5 key-value coding approaches in Cocoa
The Unix Geek. An Introduction to Key-Value Coding in Cocoa.
Thecacao. Key-Value Coding (KVC) and Generic Programming.

I think KVC is the same as the properties in C#. It is easy to understand how it's implemented. For example:
CodeProject. Implementing Properties in C++.

I think the same can be implemented much easier:
#include <iostream>
using namespace std;

class CPerson
{
char* firstName;
char* lastName;

void setValue(char*& var, const char* value)
{
if (var)
{
free(var);
var = NULL;
}
if (value == NULL)
return;
var = strdup(value);
}

public:
CPerson() : firstName(NULL), lastName(NULL) {}
~CPerson()
{
if (firstName)
free(firstName);
if (lastName)
free(lastName);
}

const char* get(const char* key)
{
if (strcmp(key, "firstName") == 0)
return firstName;
if (strcmp(key, "lastName") == 0)
return lastName;
return NULL;
}

void set(const char* key, const char* value)
{
if (strcmp(key, "firstName") == 0)
return setValue(firstName, value);

if (strcmp(key, "lastName") == 0)
return setValue(lastName, value);
return;
}

};

int main (int argc, char * const argv[])
{
CPerson person;
person.set("firstName", "Pavel");
person.set("lastName", "Gnatyuk");
cout << "Name: " << person.get("firstName") << endl;
cout << "LastName: " << person.get("lastName") << endl;
return 0;
}
It is a very simple way. I've never seen NSKeyCodingValue protocol implementation in Cocoa. Of course, it is a really generic and more complicated solution.

No comments:

Post a Comment