Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The only nice discussion I know is at Mike Ash's <a href="http://mikeash.com/pyblog//friday-qa-2009-03-27-objective-c-message-forwarding.html">blog post</a>. It's not that hard, actually. </p> <p>I once needed to split a big <code>NSManagedObject</code> subclass into two, but decided to keep the fact an implementation detail so that I don't have to rewrite other parts of my app. So, I needed to synthesize getter and setter which sends <code>[self foo]</code> to <code>[self.data foo]</code>, automatically. </p> <p>To achieve that, I did the following:</p> <ol> <li><p>Prepare the new method, already in my class.</p> <pre><code>- (id)_getter_ { return objc_msgSend(self.data, _cmd); } - (void)_setter_:(id)value { objc_msgSend(self.data, _cmd,value); } </code></pre> <p>Note that <code>_cmd</code> has the selector in it. So, usually, <code>_cmd</code> is either <code>@selector(_getter_)</code> or <code>@selector(_setter_)</code> in these methods, but I'm going to plug the implementation of <code>_getter_</code> as the implementation of <code>foo</code>. Then, <code>_cmd</code> contains <code>@selector(foo)</code>, and thus calls <code>self.data</code>'s <code>foo</code>.</p></li> <li><p>Write a generic synthesizing method:</p> <pre><code>+(void)synthesizeForwarder:(NSString*)getterName { NSString*setterName=[NSString stringWithFormat:@"set%@%@:", [[getterName substringToIndex:1] uppercaseString],[getterName substringFromIndex:1]]; Method getter=class_getInstanceMethod(self, @selector(_getter_)); class_addMethod(self, NSSelectorFromString(getterName), method_getImplementation(getter), method_getTypeEncoding(getter)); Method setter=class_getInstanceMethod(self, @selector(_setter_:)); class_addMethod(self, NSSelectorFromString(setterName), method_getImplementation(setter), method_getTypeEncoding(setter)); } </code></pre> <p>Note that this is a class method. So <code>self</code> stands for the class. Note also that I didn't hardcode type encodings (which tells Objective-C runtime what the arguments of the particular method are). The syntax of type encodings is documented, but constructing by hand is very error-prone; I wasted a few days that way until Mike Ash told me to stop it. Generate it using an existing method.</p></li> <li><p>Generate forwarders at the earliest possible time:</p> <pre><code> +(void)load { for(NSString*selectorName in [NSArray arrayWithObjects:@"foo", @"bar", @"baz",nil]){ [self synthesizeForwarder:selectorName]; } } </code></pre> <p>This generates <code>foo</code>, <code>setFoo:</code>, <code>bar</code>, <code>setBar:</code>, and <code>baz</code>, <code>setBaz:</code>.</p></li> </ol> <p>Hope this helps!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload