objective-c中的功能注入

objective-c中的功能注入,objective-c,function-pointers,Objective C,Function Pointers,我有一个随机数生成器(RNG)函数 -(double) generateRandomNumber { ... do some stuff return randomNumber; } 我有一个函数,它调用这个随机数生成器函数来完成一项任务——类似于 -(double) GenerateSellPrice { double randomNumber; randomNumber = [self generateRandomNumber]; return value

我有一个随机数生成器(RNG)函数

-(double) generateRandomNumber
{
   ... do some stuff
   return randomNumber;
}
我有一个函数,它调用这个随机数生成器函数来完成一项任务——类似于

-(double) GenerateSellPrice {
   double randomNumber;

   randomNumber = [self generateRandomNumber];

   return value*randomNumber;
}
我想对其进行修改,以便将随机数生成器函数实际传递到GenerateSellPrice函数中,以便我可以为不同的目的(即单元测试、不同范围等)交换不同的RNG


如何声明RNG函数,使其以我可以传递它的形式(我假设它是函数指针)?如何声明GenerateSellPrice以接受函数作为参数?然后如何调用该函数

最简单的方法是使用“选择器”对象。您可以通过执行以下操作来声明选择器

@selector(generateRandomNumber)
一旦有了选择器对象,就可以使用

SEL randomNumberFunction; // Most likely passed in as a parameter
NSObject *generatorObject;
[generatorObject performSelector:randomNumberFunction];

最简单的方法是使用“选择器”对象。您可以通过执行以下操作来声明选择器

@selector(generateRandomNumber)
一旦有了选择器对象,就可以使用

SEL randomNumberFunction; // Most likely passed in as a parameter
NSObject *generatorObject;
[generatorObject performSelector:randomNumberFunction];

经典的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)];
现代实践可能需要一个block(
double(^)(
)参数。块的语法稍微难看一点,但它带来的强大功能在这种情况下很有用。您可以从编译器获得更好的类型检查,并且可以方便地内联生成块,而不必编写整个类和方法

在这种情况下,您可以声明

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

   randomNumber = rngBlock();

   return value*randomNumber;
}
并称之为

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

或者对于任何其他返回
double
的块,经典的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)];
现代实践可能需要一个block(
double(^)(
)参数。块的语法稍微难看一点,但它带来的强大功能在这种情况下很有用。您可以从编译器获得更好的类型检查,并且可以方便地内联生成块,而不必编写整个类和方法

在这种情况下,您可以声明

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

   randomNumber = rngBlock();

   return value*randomNumber;
}
并称之为

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

或者,对于任何其他返回双精度的块,您可以将PRNG声明为Objective-C块,并像任何其他对象一样传递它们。有一些关于这个主题的信息

您可以将PRNG声明为Objective-C块,并像其他任何对象一样传递它们。有一些关于这个主题的信息

用积木计算出来。对于那些想知道我是如何做到这一点的人,我在调用类(classA)中将我的RNG声明为类变量

double(^generateRandomNumber)(void) = ^{   
   ...do stuff;   
   return randomNumber; 
};
然后在我调用的类(classB)中声明了我的函数

然后简单地从classA调用函数,就像这样

double (^func)(void) = generateRandomNumber;
double value = [classB generateSellPriceWithGenerator:func];

用积木算出来的。对于那些想知道我是如何做到这一点的人,我在调用类(classA)中将我的RNG声明为类变量

double(^generateRandomNumber)(void) = ^{   
   ...do stuff;   
   return randomNumber; 
};
然后在我调用的类(classB)中声明了我的函数

然后简单地从classA调用函数,就像这样

double (^func)(void) = generateRandomNumber;
double value = [classB generateSellPriceWithGenerator:func];

我已经提出了一个我自己的解决方案,我会选择它作为一个更完整的答案,但是我已经放弃了帮助我实现这一目标的答案的投票!我已经提出了一个我自己的解决方案,我会选择它作为一个更完整的答案,但是我已经放弃了帮助我实现这一目标的答案的投票!