Вызвать неопределенный метод в том же потоке?

Я хочу написать что-то вроде этого:

- (int)someMethod:(SEL)theSelector {

    NSObjet *i = func(...);
    i = theSelector(i); //replace this
    i = func2(...);
    return i;
}

Итак, у меня есть некоторые постоянные функции, которые я знаю и могу просто написать. У меня также есть неопределенная функция, которую я должен передать как параметр.

Я не могу использовать такие конструкции, как performSelector:, потому что они даже выполняются в другом цикле NSRunLoop.

И я не могу передавать блоки этой функции из-за специфического кода.

Как решить эту проблему? Кажется, objc_msgSend может помочь, но я не знаю, как правильно его использовать.


person Gargo    schedule 22.08.2014    source источник
comment
возможный дубликат Как передать @selector в качестве параметра?   -  person thierryb    schedule 22.08.2014
comment
Вам следует перечитать документацию. performSelector: эквивалентен прямому вызову метода, но полезен в таких случаях, как ваш, когда вы заранее не знаете точный селектор. Он не откладывает вызов до следующей итерации цикла выполнения. Если бы это было так, он не смог бы вернуть значение, поскольку оно было бы неопределенным.   -  person Steve Madsen    schedule 22.08.2014
comment
МОЙ БОГ. Как передать селектор в качестве параметра?! я его уже прошел. Купите очки, если не видите.   -  person Gargo    schedule 22.08.2014
comment
Стиву Мэдсену, я знаю, что performSelector: не является эквивалентом прямого вызова, потому что он не возвращает результат перед следующей строкой кода. Или performSelector: отличается от performSelector:...afterDelay:?   -  person Gargo    schedule 22.08.2014
comment
to thierryb, удалите свою глупую отметку, возможный дубликат. Если вы не можете понять, то прочитайте следующее. Вы дали мне ссылку о том, как передать метод только другому методу. НО я его уже прошел и спрашиваю как им пользоваться. Так что ваша ссылка совершенно бесполезна   -  person Gargo    schedule 22.08.2014


Ответы (2)


Используйте NSInvocation. Вот пример кода.

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: [[target class] instanceMethodSignatureForSelector:theSelector]];
[invocation setSelector:theSelector];
[invocation setTarget:target];
[invocation setArgument:&blockUserInfo atIndex:2]; // Argument 2 is the first argument in an NSInvocation, arg0 is 'self' and arg1 is '_cmd'.
[invocation invoke];
[invocation getReturnValue:&success];

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

Тьерри

person thierryb    schedule 22.08.2014
comment
Извините, я не могу проверить это сегодня. Возвращает ли он значение сразу, как если бы я вызывал эту функцию напрямую? - person Gargo; 22.08.2014

Во-первых, селектор — это просто имя метода. Вам нужен объект, чтобы отправить его. Я предполагаю, что это self.

Проще всего в этом случае использовать performSelector:onObject: (поскольку это метод, который принимает один аргумент-указатель на объект):

i = [self performSelector:theSelector withObject:i];

Это то же самое, что и прямой вызов метода (за исключением накладных расходов на сам вызов performSelector). Он не делает это асинхронно или после задержки или чего-то еще; ты смущен.

Если вы хотите узнать, как это сделать через objc_msgSend():

id (*func)(id, SEL, id) = (id (*)(id, SEL, id))objc_msgSend;
i = func(self, theSelector, i);

Обратите внимание, что вы должны сначала привести objc_msgSend к типу указателя функции, соответствующему базовой реализующей функции (которая имеет два скрытых параметра в начале, self; и _cmd, селектор). Это будет полностью идентично прямому вызову метода на уровне машинного кода. Вы можете себе представить, что компиляторы компилируют вызовы сообщений.

person newacct    schedule 22.08.2014
comment
прежде всего, селектор НЕ является ИМЯ МЕТОДА. Сначала прочтите теорию. - person Gargo; 23.08.2014
comment
@Gargo: Эм, простите? Почему бы тебе сначала не прочитать свой материал, прежде чем извергать ахинею? Селектор — это уникальная строка, используемая исключительно в качестве имен методов в Objective-C. - person newacct; 23.08.2014
comment
Да, это уникальный идентификатор, имя метода NSStringFromSelector(theSelector). В базе данных имя и идентификатор тоже означают разные вещи. - person Gargo; 23.08.2014
comment
@Gargo: в реализации Apple селектор — это указатель на начало строки C, заканчивающейся нулем. В любом случае смысл селектора в том, что есть только один селектор с данной строкой. Строка — это сущность селектора. - person newacct; 24.08.2014