OBJECTIVE-C Block Implementation Code Analysis

Source: Internet
Author: User

Block internal structure

Let's write a block

void Exampleblock () {    //nsconcretestackblock    int a = 1;    __block int b = 2;    Int (^blocktest0) (int c) = ^ (int c) {        return a + B + C;    };    int c = 3;    BlockTest0 (c);    Nsconcreteglobalblock    Void (^blocktest2) (void) = ^ (void) {        ;    };    BlockTest2 ();}

Turn the clang into C analysis.

CLANG-REWRITE-OBJC BLOCK.C

To be able to see that their definition is

struct __exampleblock_block_impl_0 {struct __block_impl impl;  struct __exampleblock_block_desc_0* desc;  int A; __block_byref_b_0 *b; By ref __exampleblock_block_impl_0 (void *fp, struct __exampleblock_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; Impl.    funcptr = FP;  desc = desc;  }};//__block_implstruct __block_impl {void *isa;  int Flags;  int Reserved; void *funcptr;};/  /__exampleblock_block_desc_0struct __exampleblock_block_impl_0 {struct __block_impl impl;  struct __exampleblock_block_desc_0* desc;  int A; __block_byref_b_0 *b; By ref __exampleblock_block_impl_0 (void *fp, struct __exampleblock_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; Impl.    funcptr = FP;  desc = desc; }};//__exampleblock_block_impl_2struct __exampleblock_block_impl_2 {struct __block_impl impl;  struct __exampleblock_block_desc_2* desc; __exampleblock_block_impl_2 (void *fp, struct __exampleblock_block_desc_2 *desc, int flags=0) {Impl.isa = &_NSCONCR    Etestackblock; Impl.    Flags = flags; Impl.    funcptr = FP;  desc = desc; }};

Initializing and running code

void Exampleblock () {    //blockTest0    int a = 1;    __ATTRIBUTE__ ((__blocks__ (ByRef))) __block_byref_b_0 B = {(void*) 0, (__BLOCK_BYREF_B_0 *) &b, 0, sizeof (__block_ BYREF_B_0), 2};    Int (*blocktest0) (int c) = (int (*) (int)) &__exampleblock_block_impl_0 ((void *) __exampleblock_block_func_0, &_ _exampleblock_block_desc_0_data, A, (__BLOCK_BYREF_B_0 *) &b, 570425344);    int c = 3;    ((Int (*) (__BLOCK_IMPL *, int)) ((__block_impl *) blockTest0)->funcptr) ((__block_impl *) blockTest0, c);    BlockTest2    Void (*blocktest2) (void) = (void (*) ()) &__exampleblock_block_impl_2 ((void *) __exampleblock_ block_func_2, &__exampleblock_block_desc_2_data);    ((Void (*) (__block_impl *)) ((__block_impl *) blockTest2)->funcptr) ((__block_impl *) blockTest2);}

Let's take a look at BlockTest2, which is composed of structural bodies IMPL, structure desc, construction method __exampleblock_block_impl_2 ()

    • *isa points to the instance object (the code is Nsconcretestackblock, in fact it should be Nsconcreteglobalblock)
    • Flags are used to indicate additional information about the block by bit bit
    • Reserved reserved variables
    • *funcptr function Pointer to the detailed block implementation of the function call address (in the code is __exampleblock_block_func_2)
static void __exampleblock_block_func_2 (struct __exampleblock_block_impl_2 *__cself) {        ;}
    • size_t reserved, this one came in 0.
    • Size of the BLOCK_SIZE structure
static struct __exampleblock_block_desc_2 {  size_t reserved;  size_t Block_size;} __exampleblock_block_desc_2_data = {0, sizeof (struct __exampleblock_block_impl_2)};

And then we're looking at Blocktest, which is 2 more variables A, b than blockTest2.

    • int A; External variable A,

    • Block_byref_b_0 *b, with a Block-modified B . Block_byref_b_0

3 more incoming values in the generated initialization code

    Int (*blocktest0) (int c) = (int (*) (int)) &__exampleblock_block_impl_0 ((void *) __exampleblock_block_func_0, &_ _exampleblock_block_desc_0_data, A, (__BLOCK_BYREF_B_0 *) &b, 570425344);
    • A is that this is directly passed in and then copied to a

    • b is the address of the transfer, is to assign the __block_byref_b_0 to B

__BLOCK_BYREF_B_0 This structure is

struct __BLOCK_BYREF_B_0 {  void *__isa;__block_byref_b_0 *__forwarding; int __flags; int __size; int b;};

__forwarding is a pointer to itself.

The initialization code for __BLOCK_BYREF_B_0 is as follows:

__ATTRIBUTE__ ((__blocks__ (ByRef))) __block_byref_b_0 B = {(void*) 0, (__BLOCK_BYREF_B_0 *) &b, 0, sizeof (__block_ BYREF_B_0), 2};

We can see that a is directly copied in, B is transferred to a structure, and then the structure of the pointer passed in, so block can not change a, can change B.

    • 570425344 This should be passed to flags.

BLOCKTEST0 's desc and blockTest2 are also different, after unfolding is

static struct __exampleblock_block_desc_0 {  size_t reserved;  size_t block_size;  void (*copy) (struct __exampleblock_block_impl_0*, struct __exampleblock_block_impl_0*);  void (*dispose) (struct __exampleblock_block_impl_0*);} __exampleblock_block_desc_0_data = {0, sizeof (struct __exampleblock_block_impl_0), __exampleblock_block_copy_0, __ EXAMPLEBLOCK_BLOCK_DISPOSE_0};

2 more function pointers Copy, Dispose, for changing the reference count of the corresponding variable before and after the call, pointing to

static void __exampleblock_block_copy_0 (struct __exampleblock_block_impl_0*dst, struct __exampleblock_block_impl_0* SRC) {_block_object_assign ((void*) &dst->b, (void*) src->b, 8/*block_field_is_byref*/);} static void __exampleblock_block_dispose_0 (struct __exampleblock_block_impl_0*src) {_block_object_dispose ((void*) Src->b, 8/*block_field_is_byref*/);}

And look at BlockTest0 's *funcptr.

static int __exampleblock_block_func_0 (struct __exampleblock_block_impl_0 *__cself, int c) {  __block_byref_b_0 *b = __cself->b; Bound by ref  Int. A = __cself->a;//bound by copy        return a + (b->__forwarding->b) + C;    }

If you can see that a uses the input copy of A, B uses a structure where b

Copyright notice: This article Bo Master original article. Blog, not reproduced without consent.

Objective-c block Implementation Code Analysis

Related Article

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.