Dynamic getters and setters with goal C

I am in a situation where I want to dynamically generate getters and setters for a class at runtime (similar to what NSManagedObject does behind the scenes). In my opinion, this is possible using the resolveInstanceMethod: method in a specific class. At this point you will have to use class_addMethod to dynamically add a selector based method. I understand this on a theoretical level, but I didn’t delve into the obj-c runtime very much, so I was curious if there were any great examples of how to do this. Most of my knowledge is taken from this article:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html

Any thoughts / examples?

+2
source share
2 answers

The only nice discussion I know is Mike Ash's blog post. This is actually not so difficult.

I once needed to split a large subclass NSManagedObjectinto two, but decided to keep the fact implementation details so that I did not have to rewrite other parts of my application. So, I needed to synthesize getter and setter, which automatically sends [self foo]to [self.data foo].

To do this, I did the following:

  • Prepare a new method already in my class.

    - (id)_getter_
    {
        return objc_msgSend(self.data, _cmd);
    }
    
    - (void)_setter_:(id)value 
    {
        objc_msgSend(self.data, _cmd,value);
    }
    

    , _cmd . , _cmd @selector(_getter_), @selector(_setter_) , _getter_ foo. _cmd @selector(foo) , , self.data foo.

  • :

    +(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));
    }
    

    , . , self . , hardcode ( Objective-C runtime, ). , ; , . .

  • :

     +(void)load  
     {
         for(NSString*selectorName in [NSArray arrayWithObjects:@"foo", @"bar", @"baz",nil]){
            [self synthesizeForwarder:selectorName];
         }
     }
    

    foo, setFoo:, bar, setBar: baz, setBaz:.

, !

+8

- , , DynamicStorage, :

https://github.com/davedelong/Demos

, , , , NSMutableDictionary ivar. , @property, , /, .. , imp_implementationWithBlock(), ( ).

+5

Source: https://habr.com/ru/post/1649180/


All Articles