2009-10-16 6 views
1

Obj-C 블록을 실험하고 있는데, 두 블록이있는 구조체를 가지고 있는데, 한 블록은 다른 블록이하는 것을 변경하는 것입니다.구조체 내의 블록이 동일한 구조체의 멤버 변수에 액세스하는 올바른 방법입니까?

이것은 단순한 무언가를하기에 정말로 둥근 길입니다 ... 더 좋은 방법이있을 수도 있지만 운동의 요지는 제가 블록을 이해하는 것입니다. 여기에 코드가 있습니다, 작동하지 않습니다, 그래서 나는 무엇을 놓치고/이해하지 못하거나 잘못하고 있습니까?

//enumerate my math operation options so i can have something more understandable 
//than 0, 1, 2, etc... also makes it easier to add operations, as opTypeTotal 
//will be 1 plus the index of the operation before it. 
typedef enum 
{ 
opTypeAdd = 0, 
opTypeSubtract = 1, 
opTypeTotal 
} opType; 

//not sure if (struct someMathStruct)* is correct, probably is wrong 
//the intent is to pass a pointer to someMathStruct, but the compiler 
//won't know about its existance until a few lines later... 
typedef (void)(^changeBlock)(opType,(struct someMathStruct)*); 
typedef (void)(^mathBlock)(int,int,int*); 

//hold two blocks, to be defined later at runtime 
typedef struct someMathStruct{ 
mathBlock doMath; 
changeBlock changeOperation; 
} SomeMath; 

//i want to declare an array of blocks of type mathBlock 
//the intent is to have the array index to correspond with the opTypes enumerated above 
//almost certain i'm doing this wrong 
mathBlock *m[opTypeTotal] = malloc(sizeof(mathBlock *)*opTypeTotal); 

//just two simple math operations as blocks 
m[opTypeAdd] = ^(void)(int a,int b,int *result){*result = a+b;}; 
m[opTypeSubtract] = ^(void)(int a,int b,int *result){*result = a-b;}; 

//this block is what's supposed to change the other block in the struct 
//it takes an opType, and a pointer to the SomeMath struct 
//is this the right way to access the member variables of the struct? 
changeBlock changeMe = ^(void)(opType a, SomeMath *b) { 
    //should make adding operations as easy as just adding cases 
switch (a) 
{ 
    case opTypeAdd: *b.doMath=m[a]; break; 
    case opTypeSubtract: 
    default: *b.doMath=m[a]; //catch-all goes to subtracting 
} 
} 

... 

SomeMath mathFun; 
int theTotal = 0; //a test int to work with 

//do i need to copy the changeMe block? 
//or can i just do what i'm doing here as the block itself isn't unique 
mathFun.changeOperation = changeMe; 

mathFun->changeOperation(opTypeAdd, &mathFun); 
mathFun->doMath(theTotal,11,&theTotal); //result should be 11 

mathFun->changeOperation(opTypeSubtract, &mathFun); 
mathFun->doMath(theTotal,3,&theTotal); //result should be 8 

NSLog(@"the result: %d",theTotal); //should output "the result: 8" 

답변

1

코드는 예상대로 작동하는 것 같다 (결과는 8) 당신은 컴파일 오류를 해결 한 후 다음과 함께

컴파일 : gcc -o test test.m -framework Foundation

#import <Foundation/Foundation.h> 

//enumerate my math operation options so i can have something more understandable 
//than 0, 1, 2, etc... also makes it easier to add operations, as opTypeTotal 
//will be 1 plus the index of the operation before it. 
typedef enum 
{ 
opTypeAdd = 0, 
opTypeSubtract = 1, 
opTypeTotal 
} opType; 

struct someMathStruct; // Forward declare this as a type so we can use it in the 
         // changeBlock typedef 

typedef void (^changeBlock) (opType,struct someMathStruct*); 
typedef void (^mathBlock) (int,int,int*); 

//hold two blocks, to be defined later at runtime 
typedef struct someMathStruct{ 
mathBlock doMath; 
changeBlock changeOperation; 
} SomeMath; 


int main() 
{ 

    //i want to declare an array of blocks of type mathBlock 
    //the intent is to have the array index to correspond with the opTypes 
    // enumerated above 
    mathBlock *m = calloc(opTypeTotal, sizeof(mathBlock *)); 

    //just two simple math operations as blocks 
    m[opTypeAdd] = ^(int a,int b,int *result){*result = a+b;}; 
    m[opTypeSubtract] = ^(int a,int b,int *result){*result = a-b;}; 

    changeBlock changeMe = ^(opType a, SomeMath *b) { 
     //should make adding operations as easy as just adding cases 
    switch (a) 
    { 
     case opTypeAdd: b->doMath = m[a]; break; 
     case opTypeSubtract: 
     default: b->doMath = m[a]; //catch-all goes to subtracting 
    } 
    }; 

    SomeMath mathFun; 
    int theTotal = 0; //a test int to work with 

    mathFun.changeOperation = changeMe; 

    mathFun.changeOperation(opTypeAdd, &mathFun); 
    mathFun.doMath(theTotal,11,&theTotal); //result should be 11 

    mathFun.changeOperation(opTypeSubtract, &mathFun); 
    mathFun.doMath(theTotal,3,&theTotal); //result should be 8 

    NSLog(@"the result: %d",theTotal); //should output "the result: 8" 
} 
+0

최고! 전방 선언은 내가 놓친 한가지였습니다. 블록에 대한 구문뿐 아니라 배열에 대한 calloc도 놓쳤습니다. 말 그대로 내 머리를 때리고. 감사! – pxl

+0

이것은 ARC에서 절대 작동하지 않습니다. –