In many of the system methods are used in the block, its essence is the function pointer Void (*block) ()
often use block instead of proxy
In C, the function is the address entry that holds the entire function, calling function execution directly.
and block, just call a piece of code, execute at the right time.
Demo:
int a = 10; __block int b = 20; void (^block) () = ^ () { printf ("a = %d\n", a); printf ("b = %d\n ", b); }; a = 50; b = 30; block ();
CLANG-REWRITE-OBJC main.m
Int main (int argc, const char * argv[]) { int a = 10; //__block-Modified, encapsulated in a structural body __BLOCK_BYREF_B_0        __ATTRIBUTE__ ((__blocks__ (ByRef))) __ block_byref_b_0 b = {(void*) 0, (__block_byref_b_0 *) &b, 0, sizeof (__Block_ BYREF_B_0), 20}; //is passed into the struct STRUCT __MAIN_BLOCK_IMPL_0 __main_block_impl_0 (...) {...} void (*block) () = (void (*) ()) &__main_block _impl_0 (void *) __main_block_func_0, &__main_block_desc_0_data, a, (__Block_byref_b_0 *) &b, 570425344); a = 50;       //Structure property value re-points to (b. __forwarding->b) = 30; //gets the struct property funcptr. That is, the encapsulated block method body. Then pass in the block instance, perform print ((void (*) (__block_impl *)) ((__block _impl *) (block)->funcptr) ((__block_impl *) block); return 0; }
--------------Disassembly:
A>
__ATTRIBUTE__ ((__blocks__ (ByRef))) __block_byref_b_0 B = {(void*) 0, (__BLOCK_BYREF_B_0 *) &b, 0, sizeof (__block_ BYREF_B_0), 20};
Parameter: (void*)0
< Span style= "Color:rgb (147, 161, 161); Font-family:consolas, ' Liberation Mono ', Menlo, Courier, monospace; font-size:13px; line-height:18px; White-space:pre; Background-color:rgb (247, 247, 249); " > ( __block_byref_b_0 b
< Span style= "Color:rgb (147, 161, 161); Font-family:consolas, ' Liberation Mono ', Menlo, Courier, monospace; font-size:13px; line-height:18px; White-space:pre; Background-color:rgb (247, 247, 249); " > 0
< Span style= "Color:rgb (147, 161, 161); Font-family:consolas, ' Liberation Mono ', Menlo, Courier, monospace; font-size:13px; line-height:18px; White-space:pre; Background-color:rgb (247, 247, 249); " > __block_byref_b_0)
20
< Span style= "Color:rgb (147, 161, 161); Font-family:consolas, ' Liberation Mono ', Menlo, Courier, monospace; font-size:12px; " > encapsulate the value of B to __BLOCK_BYREF_B_0 the structure of the body. "Encapsulated structure for __block decorated values"
struct __block_byref_b_0 {void *__isa;//Current object pointer __block_byref_b_0 *__forwarding;//current struct pointer, __forwarding stored from Your own address. Execute int __flags with __block decoration; Mark int __size; struct size int b; Value};
B> passed to the method in the struct body
void (*block) () = (void (*) ()) &__main_block_impl_0 ((void *) __main_block_func_0, &__main_block_desc_0_data, A, (__BLOCK_BYREF_B_0 *) &b, 570425344);
Passed:(void *)__main_block_func_0//Storage block Method Body "is here two print", the following *FP
& __main_block_desc_0_data // Address, block description data
A//value transfer
(__block_byref_b_0*) &bPass the address of B, structure wrapper
570425344
< Span style= "Color:rgb (25, 95, 145); Font-family:consolas, ' Liberation Mono ', Menlo, Courier, monospace; font-size:12px; " > to: Instance method of block
Struct __main_block_impl_0 { struct __block_impl impl; struct __main_block_desc_0* Desc; int a; // 10 __Block_byref_b_0 *b; // by ref //call this method, the implementation of the method is within parentheses. The parameters passed above are assigned here __main_block_impl_0 (void *fp, struct __main_block_desc_0 * desc, int _a, __block_byref_b_0 *_b, int flags=0) : a (_a), b (_b- >__forwarding) { impl.isa = &_nsconcretestackblock; impl . Flags = flags;&nBsp; impl. Code print performed by funcptr = fp; //. __main_block_func_0 desc = desc; } }
The methods inside the block are encapsulated here.
static void __main_block_func_0 (struct __main_block_impl_0 *__cself) { __block_byref_b_0 *b = __cself->b; // bound by ref int a = __cself->a; // bound by copy printf ("a = %d\n", a); printf ("b = %d\ N ", (b->__forwarding->b)); }
struct __block_impl {void *isa; int Flags; int Reserved; void *funcptr; };
C>
A = 50; (b.__forwarding->b) = 30;
The b here is __block_byref_b_0 b .
Gets the attribute __forwarding in the struct and points it to the value 30;
Use __block and do not use. Always a pass, one is a value.
After being compiled into C + +, it is found that when __block decorated objects are used, they are encapsulated into one type of struct.
Block bottom Implementation Disassembly