Функция впрыска в target-c - PullRequest
       1

Функция впрыска в target-c

1 голос
/ 21 апреля 2011

У меня есть функция генератора случайных чисел (RNG).

-(double) generateRandomNumber
{
   ... do some stuff
   return randomNumber;
}

У меня есть функция, которая вызывает эту функцию генератора случайных чисел для выполнения задачи - что-то вроде

-(double) GenerateSellPrice {
   double randomNumber;

   randomNumber = [self generateRandomNumber];

   return value*randomNumber;
}

Я хочу изменить это так, чтобы функция генератора случайных чисел фактически передавалась в функцию GenerateSellPrice, чтобы я мог менять и использовать разные ГСЧ для различных целей (например, модульное тестирование, разные диапазоны и т. Д.).

Как мне объявить функцию RNG, чтобы она была в форме, которую я могу передать (я предполагаю, что это указатель на функцию)? Как мне объявить GenerateSellPrice для принятия функции в качестве параметра? И как мне тогда вызвать функцию?

Ответы [ 4 ]

2 голосов
/ 21 апреля 2011

Классический шаблон Objective-C будет принимать аргумент аргумента селектора (SEL) и объекта (id):

  -(double) GenerateSellPriceWithRNG:(id)rngObject selector:(SEL)rngSelector
       double randomNumber;

       randomNumber = [rngObject performSelector:rngSelector];

       return value*randomNumber;
    }

и позвоните по номеру

[self GenerateSellPrinceWithRNG:self selector:@selector(generateRandomNumber)];

Современная практика, вероятно, будет принимать параметр блока (double (^)()). Синтаксис для блока немного уродливее, но мощность, которую он приносит, полезна в этом сценарии. Вы получаете лучшую проверку типов из компилятора и можете легко сгенерировать встроенный блок там, где это удобно, а не писать целый класс и метод.

В этом случае вы можете объявить

-(double) GenerateSellPriceWithRNG:(double (^)())rngBlock {
   double randomNumber;

   randomNumber = rngBlock();

   return value*randomNumber;
}

и позвоните по номеру

[self GenerateSellPriceWithRNG:^{ return [self generateRandomNumber]; }];

или с любым другим блоком, который возвращает double.

2 голосов
/ 21 апреля 2011

Вы можете объявить свои PRNG как блоки Objective-C и передавать их, как любой другой объект.http://www.mikeash.com/pyblog/friday-qa-2008-12-26.html имеет некоторую информацию по этому вопросу.

1 голос
/ 21 апреля 2011

Самый простой способ сделать это - использовать объект «селектор». Вы можете объявить селектор, выполнив следующее

@selector(generateRandomNumber)

Если у вас есть объект селектора, вы используете

SEL randomNumberFunction; // Most likely passed in as a parameter
NSObject *generatorObject;
[generatorObject performSelector:randomNumberFunction];
0 голосов
/ 21 апреля 2011

Разобрался с использованием блоков. Для тех, кто хочет знать, как я это сделал, я объявил свой ГСЧ в своем вызывающем классе (classA) как переменную класса

double(^generateRandomNumber)(void) = ^{   
   ...do stuff;   
   return randomNumber; 
};

Затем объявил мою функцию в моем вызываемом классе (classB)

-(double) generateSellPriceWithGenerator:(double(^)(void))generator {
   double randomNumber;

   randomNumber = generator();

   return value*randomNumber;
}

А потом просто вызывается функция из класса А, как это так

double (^func)(void) = generateRandomNumber;
double value = [classB generateSellPriceWithGenerator:func];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...