Block Structure (1)

Source: Internet
Author: User
A block is actually an object with its own attributes. The structure is as follows:
  • ISA pointer. All objects have this pointer for message transmission and other functions (IAS generally points to the parent class and metadata class)
  • Flags, used to indicate additional block information by bit
  • Reserved, reserved variable.
  • Invoke, function pointer, pointing to the function call address implemented by the specific block.
  • Descriptor, indicating the additional description of the block, mainly the size and pointer of the copy and dispose functions.
  • Variables, a variable from capture, block can access its external local variables because these variables (or the address of the variable) are copied to the struct.

     

We use the clang-rewrite-objc command to decompile the. M file to obtain the. cpp file. M contains the following generation
-(void )test3{    NSString *_person2=@"person2";    NSLog(@"block init:%@,%p,%p",_person2,&_person2,_person2);    void (^myBlock)(int) = ^(int num) {        NSLog(@"block excuteing:%@,%p,%p",_person2,&_person2,_person2);    };    _person2=@"person22";    NSLog(@"block excutebefore:%@,%p,%p",_person2,&_person2,_person2);    myBlock(1);    NSLog(@"block excuteafter:%@,%p,%p",_person2,&_person2,_person2);}

 

Obtain some source code

// Here it should be a constant in the registration code, which will be used below

#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_0 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"KDBlockTest dealloc",19};static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_1 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"person2",7};static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_2 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"block init:%@,%p,%p",19};static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_3 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"block excuteing:%@,%p,%p",24};static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_4 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"person22",8};static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_5 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"block excutebefore:%@,%p,%p",27};static __NSConstantStringImpl __NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_6 __attribute__ ((section ("__DATA, __cfstring"))) = {__CFConstantStringClassReference,0x000007c8,"block excuteafter:%@,%p,%p",26};
// Here is the structure of the block object
// Imp: function pointer pointing to the function implemented by the specific block
// _ Person2: intercepted variable
// Isa, flags, funcptr, and desc will be mentioned later.
struct __KDBlockTest__test3_block_impl_0 {  struct __block_impl impl;  struct __KDBlockTest__test3_block_desc_0* Desc;  NSString *_person2;  __KDBlockTest__test3_block_impl_0(void *fp, struct __KDBlockTest__test3_block_desc_0 *desc, NSString *__person2, int flags=0) : _person2(__person2) {    impl.isa = &_NSConcreteStackBlock;    impl.Flags = flags;    impl.FuncPtr = fp;    Desc = desc;  }
// Functions implemented by block
static void __KDBlockTest__test3_block_func_0(struct __KDBlockTest__test3_block_impl_0 *__cself, int num) {  NSString *_person2 = __cself->_person2; // bound by copy        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_3,_person2,&_person2,_person2);    }
// Copy function, which can be copied to the stack
static void __KDBlockTest__test3_block_copy_0(struct __KDBlockTest__test3_block_impl_0*dst, struct __KDBlockTest__test3_block_impl_0*src) {_Block_object_assign((void*)&dst->_person2, (void*)src->_person2, 3/*BLOCK_FIELD_IS_OBJECT*/);}
// Corresponding release function
static void __KDBlockTest__test3_block_dispose_0(struct __KDBlockTest__test3_block_impl_0*src) {_Block_object_dispose((void*)src->_person2, 3/*BLOCK_FIELD_IS_OBJECT*/);}
// Block Object Description (size, etc)
static struct __KDBlockTest__test3_block_desc_0 {  size_t reserved;  size_t Block_size;  void (*copy)(struct __KDBlockTest__test3_block_impl_0*, struct __KDBlockTest__test3_block_impl_0*);  void (*dispose)(struct __KDBlockTest__test3_block_impl_0*);} __KDBlockTest__test3_block_desc_0_DATA = { 0, sizeof(struct __KDBlockTest__test3_block_impl_0), __KDBlockTest__test3_block_copy_0, __KDBlockTest__test3_block_dispose_0};
// This is the objc test function.
static void _I_KDBlockTest_test3(KDBlockTest * self, SEL _cmd) {    NSString *_person2=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_1;    NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_2,_person2,&_person2,_person2);    void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test3_block_impl_0((void *)__KDBlockTest__test3_block_func_0, &__KDBlockTest__test3_block_desc_0_DATA, _person2, 570425344);    _person2=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_4;    NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_5,_person2,&_person2,_person2);    ((void (*)(__block_impl *, int))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock, 1);    NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_6,_person2,&_person2,_person2);}

 

Simple Analysis: 1) block initialization, combined with constructors:
__KDBlockTest__test3_block_impl_0(void *fp, struct __KDBlockTest__test3_block_desc_0 *desc, NSString *__person2, int flags=0) : _person2(__person2) {    impl.isa = &_NSConcreteStackBlock;    impl.Flags = flags;    impl.FuncPtr = fp;    Desc = desc;  }
void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test3_block_impl_0((void *)__KDBlockTest__test3_block_func_0, &__KDBlockTest__test3_block_desc_0_DATA, _person2, 570425344);
Passed in parameters: function pointer, block description, external variable _ person2. At this time, _ person2 was deeply copied in the block (in fact, I didn't see from where it was actually a deep copy, hope you can enlighten me) 2 ). execute Block
((void (*)(__block_impl *, int))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock, 1);

In fact, the function _ kdblocktest _ test3_block_func_0 pointed to by the block function pointer is called, and the block itself is passed as a parameter.

static void __KDBlockTest__test3_block_func_0(struct __KDBlockTest__test3_block_impl_0 *__cself, int num) {  NSString *_person2 = __cself->_person2; // bound by copy        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_51f509_mi_3,_person2,&_person2,_person2);    }

It is worth noting that we modify _ person2 before execution, but it does not affect the interior of the block, because when constructing the block, the block has already made a deep copy of the intercepted variables. When the block is executed, the function _ kdblocktest _ test3_block_func_0 is called directly. Inside the function, the _ person2 object copied by the block is referenced, I think this should be the feature of block interception variables.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.