Можно ли передать метод в качестве аргумента в Objective-C? - PullRequest
21 голосов
/ 06 февраля 2009

У меня есть метод, который изменяется одним вызовом метода внутри, и я хотел бы передать метод / сигнатуру метода, на который он изменяется, в качестве аргумента ... это возможно в Objective C или это слишком на что надеяться?

Ответы [ 3 ]

25 голосов
/ 06 февраля 2009

NSInvocation - это класс для обобщения вызовов методов в объекте. Вы можете установить селектор (сигнатуру метода), установить аргументы по индексу. Затем вы можете установить цель и вызов вызова для запуска вызова или оставить цель неустановленной и использовать invokeWithTarget: в каком-то цикле для вызова этого на многих объектах.

Я думаю, что это работает примерно так:

NSInvocation *inv = [[NSInvocation alloc] init];
[inv setSelector:@selector(foo:bar:)];
[inv setArgument:123 atIndex:0];
[inv setArgument:456 atIndex:1];

for (MyClass *myObj in myObjects) {
  [inv invokeWithTarget:myObj];
}

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

-(void)fooWithMethod:(SEL)selector;

Затем назначает селектор объекту вызова для вызова его на объектах.

10 голосов
/ 08 февраля 2009

Или, если вы используете подход fooWithMethod:(SEL)selector, просто наберите [myObject performSelector:selector], если у него нет других аргументов.

Подробнее см. NSObject .

3 голосов
/ 28 сентября 2010

Как сказано выше, вы можете передать селектор метода, который вы хотите вызвать. Используя селектор, существуют разные способы вызова метода:

  1. с использованием NSObject s performSelector:, performSelector:withObject: и performSelector:withObject:withObject: методов
  2. с использованием NSInvocation объекта
  3. или напрямую, используя objc_msgSend или objc_msgSend_stret
  4. используя IMP того метода, который вы можете получить, используя methodForSelector:

Какой из них использовать, действительно зависит от ситуации. Если производительность не критична, я выберу 1, если вам нужно передать 0, 1 или 2 объекта. Если методы performSelector:... не совпадают, я бы выбрал 2 или 3. Поскольку настройка объекта NSInvocation требует большого количества стандартного кода, я предпочитаю 3, но я полагаю, что это вопрос личного выбора, если только нет проблемы с производительностью.

Если производительность этих вызовов методов имеет значение, я бы использовал 3 или 4. 3 должно быть быстрее, если вы не можете кэшировать IMP s. Но в зависимости от вашего кода это может быть неосуществимо или не очень помогает. Так что здесь вы должны профилировать код и посмотреть, какой из них лучше для вас.

...