Search code examples
objective-cruntimemessagingconceptual

Objective-C messaging, smartly dealing with unknown messages


Is there a way to do something similar to KVC but use the message name as the key itself? For example, rather than valueForKey:, is there a way for an object to respond to all messages?

For example, say you have an XML document:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ...>
<employees>
  <employee>
    <name>Bill</name>
    <department>Accounting</department>
  </employee>
  <employee>
    <name>John</name>
    <department>Human Resources</department>
  </employee>
</employees>

Besides using the already-available NSXMLDocument and co., would there be a way to implement some sort of abstraction so you could do:

MyXML *xmlDoc = [[MyXML alloc] initWithContentsOfFile:@"test.xml"];

NSLog (@"%@", [[[xmlDoc employees] first] department]);

[[[xmlDoc employees] first] setDepartment:@"Management"];

I chose XML just as an example, but I want to know whether this is possible at all, and whether or not it involves getting too close to the Objective-C runtime or whether it is supported by the runtime itself, and how I would go about implementing something like this. This is purely for experimental purposes and I understand that there will likely be significant performance costs.

EDIT:
If possible, I'd like to avoid existing frameworks such as Cocoa and use the base Objective-C object Object.


Solution

  • You need to implement forwardInvocation: and methodSignatureForSelector: to handle unrecognized messages. It is described in the NSObject reference.

    EDIT: Wikipedia has an example of how forwarding can be accomplished for Object, basically by implementing forward: and performv:.