objective c - A function that can return an object or a primitive type: is it possible? -


note: beginning of question similar (the first part same) one: link
however, final question different.

i'm implementing "code injector class", through method swizzling can give possibility this:

flcodeinjector *injector = [flcodeinjector injectorforclass:[self class]]; [injector injectcodebeforeselector:@selector(aselector:) code:^{     nslog(@"this code should injected"); }]; 

aselector can method variable number of arguments, , variable return type. arguments / , return type can objects or primitive type.

first, attach code of injectcodebeforeselector: let understand i'm doing (i removed not interesting parts of code):

- (void)injectcodebeforeselector:(sel)method code:(void (^)())completionblock {      nsstring *selector = nsstringfromselector(method);      [self.dictionaryofblocks setobject:completionblock forkey:selector];      nsstring *swizzleselector = [nsstring stringwithformat:@"swz%@", selector];      //nsmethodsignature *signature = [self.mainclass instancemethodsignatureforselector:method];      // add new method swizzled class     method origmethod = class_getinstancemethod(self.mainclass, nsselectorfromstring(selector));     const char *encoding = method_gettypeencoding(origmethod);       [self addselector:nsselectorfromstring(swizzleselector) toclass:self.mainclass originalselector:method methodtypeencoding:encoding];     swizzleme(self.mainclass, nsselectorfromstring(selector), nsselectorfromstring(swizzleselector));  }      -(void)addselector:(sel)selector toclass:(class)aclass originalselector:(sel)originalsel methodtypeencoding:(const char *)encoding {      //nsmethodsignature *signature = [aclass methodsignatureforselector:originalsel];     nsmethodsignature *signature = [nsmethodsignature signaturewithobjctypes:encoding];     const char *type = [signature methodreturntype];     imp implementation = (imp)intgenericfunction;       if (strcmp(@encode(id), type) == 0) {         // argument object         implementation = objectgenericfunction;     }     else if (strcmp(@encode(int), type) == 0)     {         // argument int         implementation = (imp)intgenericfunction;     }     else if (strcmp(@encode(long), type) == 0)     {         // argument long         implementation = (imp)longgenericfunction;      }     else if (strcmp(@encode(double), type) == 0)     {         // argument double         implementation = (imp)doublegenericfunction;     }     else if (strcmp(@encode(float), type) == 0)     {         // argument float         implementation = (imp)floatgenericfunction;     }     else     {         // argument char or others         implementation = (imp)intgenericfunction;     }        class_addmethod(aclass,                     selector,                     implementation, encoding); } 

what happening here? basically, basing on expected return type of original selector, add new method object correct return type, apply swizzle.

all working correctly, i'd know if it's possible "compact" following code (some syntax don't know or i'm missing), because each return type have function identical others, returned type different. attach 2 of them example:

int intgenericfunction(id self, sel cmd, ...) {      flcodeinjector *injector = [flcodeinjector injectorforclass:[self class]];     [injector executeblockforselector:cmd];       va_list arguments, copiedarguments;     va_start ( arguments, cmd );     va_copy(copiedarguments, arguments);     va_end(arguments);      void * returnvalue = getreturnvalue(self, cmd, copiedarguments);      int returnedint = *(int *)returnvalue;     return returnedint; }  double doublegenericfunction(id self, sel cmd, ...) {      flcodeinjector *injector = [flcodeinjector injectorforclass:[self class]];     [injector executeblockforselector:cmd];       va_list arguments, copiedarguments;     va_start ( arguments, cmd );     va_copy(copiedarguments, arguments);     va_end(arguments);      void * returnvalue = getreturnvalue(self, cmd, copiedarguments);      double returneddouble = *(double *)returnvalue;     return returneddouble; } 

as can see, functions identical, different cast before return, , return type of function.

i'm implementing in correct way, or there more efficient way it? thanks

you're correct you'll need write different imp each return type, @ least unless drop down assembly dispatch, way objc_msgsend does. (even function requires couple different type variants, though.) however, if difference couple of type names, may able define macro reduces boilerplate:

// macro syntax off top of head; may not correct. #define generic_function_for_type(type) type type##genericfunction(id self, sel cmd, ...) { \     ...other lines omitted... \     type returnedvalue = *(type *)returnvalue; \     return returnedvalue; \ }  generic_function_for_type(int) generic_function_for_type(double) ...etc... 

Comments

Popular posts from this blog

image - ClassNotFoundException when add a prebuilt apk into system.img in android -

I need to import mysql 5.1 to 5.5? -

Java, Hibernate, MySQL - store UTC date-time -