Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
649 views
in Technique[技术] by (71.8m points)

objective c - How does a Block capture the variables outside of its enclosing scope?

I know that an Objective-C Block can capture and set the value of variables outside of its enclosing scope. How does it do that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It's actually fairly straightforward and described in Clang's Block Implementation Spec, in the "Imported Variables" section.

When the compiler encounters a Block like:

^{ if( numBalloons > numClowns) abort(); }

it creates a literal structure that includes -- among other things -- two elements that are important here. There's a function pointer to the executable code in the Block, and a const field for each variable that's referred to inside the Block. Something like this:

struct __block_literal_1 {
    /* other fields */
    void (*invoke)(struct __block_literal_1 *);
    /* ... */
    const int numBalloons;
    const int numClowns;
};

Notice that the invoke function will take a pointer to a struct of the kind that's being defined right here; that is, the Block passes itself in when executing its code. Thus, the code gets access to the members of the structure.

Right after the declaration, the compiler creates a definition of the Block, which simply uses the referenced variables to initialize the correct fields in the struct:

struct __block_literal_1 __block_literal_1 = {
    /* Other fields */
    __block_invoke_2,  /* This function was also created by the compiler. */
    /* ... */
    numBalloons,  /* These two are the exact same variables as */ 
    numClowns     /* those referred to in the Block literal that you wrote. *
 };

Then, inside the invoke function, references to the captured variables are made like any other member of a struct, the_block->numBalloons.

The situation for object-type variables is a little more complicated, but the same principle applies.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...