Cómo crear métodos mágicos en Objective C

I am trying to develop a set of magic findByX methods in a generic Model class that eventually will issue queries to Core Data using NSPredicate objetos:

  • (id)findByName;
  • (id)findByCreated;
  • ...

Following advice from a pregunta SO anterior I can intercept messages that request non-existent methods by overriding resolveInstanceMethod:

#include <objc/runtime.h>

+ (BOOL) resolveInstanceMethod:(SEL)aSel {
  if (aSel == @selector(resolveThisMethodDynamically)) {
    class_addMethod([self class], aSel, (IMP) dynamicMethodIMP, "v@:");
    return YES;
  }
  return [super resolveInstanceMethod:aSel];
}

void dynamicMethodIMP(id self, SEL _cmd) {
  NSLog(@"Voilà");
}

Sin embargo, cuando trato de usar [myObject resolveThisMethodDynamically] the compiler raises the following error:

"No visible @interface for 'MyModel' declares the selector 'resolveThisMethodDynamically'"

which makes sense, since there isn't any declaration of that method. So, what am I missing here? Is there any best practice to accomplish this?

¡Gracias!

preguntado el 28 de agosto de 12 a las 10:08

This is a XY problem. See RestKit for how to implement findAll features. Specifically, NSManagedObject+ActiveRecord category. -

3 Respuestas

I'm not sure if it's exactly what you're after, but here are a couple of helpful resources for this sort of Core Data functionality:

MagicalRecord is a small framework for Core Data that makes it work a lot like ActiveRecord from the Ruby world. In particular, it implements a lot of the fetching functionality you're after, I think. Check out the categories it adds to NSManagedObject.

¡Espero que esto ayude!

Respondido 28 ago 12, 10:08

This got me pretty curious, so I searched around and there are a number of options. Este hilo sums them up. Personally, I'm sympathetic to the argument that if you add a method at run-time, you should not be choosing the selectors at compile time, but do so at runtime as well. So, use NSSelectorFromString and so on, with some various preprocessor directives to suppress warnings in such cases.

¡Espero que esto ayude!

contestado el 23 de mayo de 17 a las 11:05

Utilice las

objc_msgSend( myObject, sel_getUid("yourMethod"), param1, param2...);

don't forget to import 'objc/message.h'

contestado el 14 de mayo de 14 a las 23:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.