هل هذه هي الطريقة الصحيحة لكتلة داخل البنية للوصول إلى متغير عضو في نفس البنية؟

StackOverflow https://stackoverflow.com/questions/1579494

سؤال

أنا أجرب كتل 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"
هل كانت مفيدة؟

المحلول

يبدو أن الرمز يعمل كما تتوقع (النتيجة 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"
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top