2011-03-21 42 views
1

enter image description here在Objective-C中实现分段周期函数的最佳方法是什么?

我需要在Objective-c中实现一种说明函数(ratio = somefunction(time))。语言实际上并不重要,因为任务似乎纯粹是算法。有没有常见的方法来做这样的事情? 接下来的东西应该很容易在设计过程中调整:

1)每个周期的小间隔数(现在是4,但它可以是3或20)。 2)f1可以改变。它是简单的函数,如f(x)= sin(x)。 3)如果我们说

f_resulting = 
    f1 for a time t1 
    f2 for a time t2 
    then again 
    f1 for a time t1 
    etc.. 

比当f1 “作品” 与F2 “作品”(t1至t2)应该是可调的。

+0

的Objective-C是* *非常不同于C. – 2011-03-21 17:25:07

+0

“最佳”是什么意思?最容易实现?最容易维护?最灵活?最高的性能? – 2011-03-21 17:27:58

回答

2

标准C本身没有闭包,所以如果您使用C函数指针,您需要构建自己的闭包 - 只需使用类实例来存储两个函数指针和持续时间以及调用方法来调用构成的周期函数。

不过苹果已经引入了块,这些块只是用闭包实现的内联函数,所以在Apple C中,您可以轻松组合功能。这是更有趣,但“最好的”,你将不得不决定...

一个例子,组成双重>双重功能。第一报头,Periodic.h:

typedef double (^Monadic)(double); 

Monadic makePeriodic(Monadic firstFunction, double firstPeriod, 
        Monadic secondFunction, double secondPeriod); 

和实现,Periodic.c:

#include "Periodic.h" 

Monadic makePeriodic(Monadic firstFunction, double firstPeriod, 
        Monadic secondFunction, double secondPeriod) 
{ 
    return Block_copy(^(double time) 
         { 
          return fmod(time, firstPeriod+secondPeriod) < firstPeriod 
           ? firstFunction(time) 
           : secondFunction(time); 
         } 
        ); 
} 

块被构造在栈上,并且可以在封闭的范围引用的局部变量和参数。因此,您不能简单地从函数返回一个块,因为它返回的范围会消失。函数Block_copy()将块及其引用的任何块移动到堆上,以使它们超出其创建范围。不再需要时,堆块必须以Block_release()发布。

和一个简单的演示:

Monadic queer = makePeriodic(^(double t) { return t * t; }, 5, 
          ^(double t) { return sqrt(t); }, 3); 

for(double ix = 0; ix <= 16; ix++) 
    printf("%f -> %f\n", ix, queer(ix)); 

Block_release(queer); // clean up 

现在你可以用这一切在一类,如果你愿意的话它适合的OBJ-C的风格。当你这样做时,你还可以发送copyrelease消息到块中,就像它是一个Obj-C对象一样。在垃圾收集的环境中,您仍然需要copy才能获得堆块,但不需要release

Periodic.h:

typedef double (^Monadic)(double); 

@interface ComposeOne : NSObject 
{ 
} 

+ (Monadic) makePeriodicWithFunction:(Monadic)firstFunction 
          forPeriod:(double)firstPeriod 
         andFunction:(Monadic)secondFunction 
          forPeriod:(double)secondPeriod; 

@end 

Periodic.M:

@implementation ComposeOne 

+ (Monadic) makePeriodicWithFunction:(Monadic)firstFunction 
          forPeriod:(double)firstPeriod 
         andFunction:(Monadic)secondFunction 
          forPeriod:(double)secondPeriod 
{ 
    Monadic result = (^(double time) 
         { 
          return fmod(time, firstPeriod+secondPeriod) < firstPeriod 
           ? firstFunction(time) 
           : secondFunction(time); 
         } 
        ); 
return [result copy]; 
} 

@end 

而简单的演示(还是用printf虽然为了方便):

Monadic queer = [ComposeOne makePeriodicWithFunction:^(double t) { return t * t; } 
              forPeriod:5 
             andFunction:^(double t) { return sqrt(t); } 
              forPeriod:3]; 
for(double ix = 0; ix <= 16; ix++) 
    printf("%f -> %f\n", ix, queer(ix)); 

[queer release]; 
+0

CRD,谢谢你的详尽解答!不过,我终于通过几个纯C函数来实现它。也许我稍后重写它。另外,感谢您使用示例的好块! – 2011-03-25 11:48:16

相关问题