2009-10-16 3 views
1

J'expérimente des blocs Obj-C et j'essaie d'avoir une structure avec deux blocs là où un bloc doit changer ce que fait l'autre bloc. C'est une façon vraiment détournée de faire quelque chose de simple ... et il peut y avoir de meilleures façons de le faire, mais le but de l'exercice est de comprendre les blocs. voici le code, ça ne marche pas, alors qu'est-ce que je manque/ne comprends pas et/ou fait mal?Est-ce la bonne façon pour un bloc à l'intérieur d'une structure d'accéder à une variable membre dans la même structure?

//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" 

Répondre

1

Le code semble fonctionner comme prévu (le résultat est 8) une fois que vous corriger les erreurs de compilation:

compilez avec: 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

génial! la déclaration avant était une chose que j'ai ratée. ainsi que la syntaxe pour les blocs. et a également manqué le calloc pour le tableau. littéralement battre ma tête par-dessus ceci. Merci! – pxl

+0

Cela ne fonctionne absolument pas sous ARC. –

Questions connexes