2011-03-21 5 views
1

enter image description hereObjective-C에서 조각 별주기 함수를 구현하는 가장 좋은 방법은 무엇입니까?

Objective-c에서 설명 된 종류의 기능 (ratio = somefunction (time))을 구현해야합니다. 언어는 실제로 중요하지 않습니다. 왜냐하면 작업은 순전히 알고리즘 적으로 보인다. 이런 일을하는 일반적인 방법이 있습니까? 다음 단계는 설계 과정에서 쉽게 조정할 수 있어야합니다.

1)주기 당 작은 간격 수 (현재는 4이지만 예를 들어 3 또는 20 일 수 있습니다). 2) f1을 변경할 수 있습니다. 그것은 f (x) = sin (x)와 같은 간단한 함수입니다. F1은 "작동"F2 대 "일」라고

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

비율 말하면 3) (T2에 T1)은 조정되어야한다.

+0

오브젝티브 C는 * * C와 매우 다른 ** –

+0

"최고"어떤 의미로? 가장 쉬운 구현 방법은? 유지 관리가 용이합니까? 가장 유연한가? 최고의 성능? –

답변

2

표준 C 자체에는 클로저가 없으므로 C 함수 포인터를 사용하는 경우 자신 만의 클로저를 만들어야합니다. 두 개의 함수 포인터와 지속 기간을 저장하는 클래스 인스턴스와 구성된 정기 함수를 호출하는 호출 메서드를 사용해야합니다.

그러나 Apple은 클로저로 구현 된 인라인 함수 인 블록을 도입 했으므로 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 함수를 통해 구현했습니다. 어쩌면 내가 나중에 다시 쓴다.또한 예제를 사용하여 좋은 블록을 주셔서 감사합니다! –

관련 문제