Как создать магические методы в Objective C

Я пытаюсь разработать набор магических методов findByX в общем классе Model, который в конечном итоге будет выполнять запросы к Core Data с использованием объектов NSPredicate:

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

Следуя совету из предыдущего вопроса SO, я могу перехватывать сообщения, запрашивающие несуществующие методы, переопределяя 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à");
}

Однако, когда я пытаюсь использовать [myObject resolveThisMethodDynamically], компилятор выдает следующую ошибку:

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

что имеет смысл, так как нет никакого объявления этого метода. Итак, что мне здесь не хватает? Есть ли лучшая практика для этого?

Спасибо!


person elitalon    schedule 28.08.2012    source источник
comment
Это проблема XY. См. RestKit, чтобы узнать, как реализовать функции findAll. В частности, категория NSManagedObject+ActiveRecord.   -  person Paul de Lange    schedule 28.08.2012


Ответы (3)


Я не уверен, что это именно то, что вам нужно, но вот несколько полезных ресурсов для такого рода функций Core Data:

MagicalRecord — это небольшой фреймворк для Core Data, который во многом похож на ActiveRecord из мира Ruby. В частности, я думаю, что он реализует множество функций извлечения, которые вам нужны. Ознакомьтесь с категориями, которые он добавляет в NSManagedObject.

Надеюсь это поможет!

person James Frost    schedule 28.08.2012

Это меня очень заинтересовало, поэтому я поискал и нашел несколько вариантов. Эта ветка суммирует их. Лично я сочувствую аргументу, что если вы добавляете метод во время выполнения, вы не должны выбирать селекторы во время компиляции, а должны делать это и во время выполнения. Итак, используйте NSSelectorFromString и т. д. с некоторыми различными директивами препроцессора для подавления предупреждений в таких случаях.

Надеюсь это поможет!

person Carl Veazey    schedule 28.08.2012

Использовать

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

не забудьте импортировать 'objc/message.h'

person Luc-Olivier    schedule 14.05.2014