Block realization

How to block is achieved

We clang compiled Objective-C correspond to documents cpp file, to see his implementation, comparison of different styles of blockdifferent,
its implementation from idea to get

The basic parameters of the Block-free

#import "ViewController.h"

typedef void(^WxsBlock) ();

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  WxsBlock blockObj = ^(){
      NSLog(@"test");
  };

  blockObj();
}

@end

We declare in ViewController.m in implementing and using a no parameters Block

Then clang compiled corresponding cpp file, we only care about Block and the corresponding code, as follows

typedef void(*WxsBlock) ();

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
};

struct __ViewController__viewDidLoad_block_impl_0 {
  struct __block_impl impl;
  struct __ViewController__viewDidLoad_block_desc_0* Desc;
  __ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

static void __ViewController__viewDidLoad_block_func_0(struct __ViewController__viewDidLoad_block_impl_0 *__cself) {
    NSLog((NSString *)&__NSConstantStringImpl__var_folders_t9_g3xrsv653kz2gr7tmgwfbfvh0000gn_T_ViewController_dd8c22_mi_0);
}

static struct __ViewController__viewDidLoad_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __ViewController__viewDidLoad_block_desc_0_DATA = { 0, sizeof(struct __ViewController__viewDidLoad_block_impl_0)};

static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
  ((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
  WxsBlock blockObj = ((void (*)())&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA));

  ((void (*)(__block_impl *))((__block_impl *)blockObj)->FuncPtr)((__block_impl *)blockObj);
}

We look to resolve

struct __block_impl {
  void *isa;
  int Flags;
  int Reserved;
  void *FuncPtr;
}

This effect is equivalent to the structure of a block "core functional class", contains a pointer pointing to the superclass,
the pointer performs the method.

  • void *isa Pointer to the superclass, the Objective-C are objects in Block, not difficult to understand that
  • int Flags Mark, I do not know what this meaning, for the time being we understand to make a marked effect.
  • int Reserved Reserved field, now do not care, but this idea can learn reserved
  • void *FuncPtr Execution pointer to the method, this method is used to block holding block pointer
static struct __ViewController__viewDidLoad_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __ViewController__viewDidLoad_block_desc_0_DATA = { 0, sizeof(struct __ViewController__viewDidLoad_block_impl_0)};

__ViewController__viewDidLoad_block_desc_0Look at the name, which is used to describe a block of,

  • size_t reserved Reserved space
  • size_t Block_size block of space
  • __ViewController__viewDidLoad_block_desc_0_DATAStructure variable declarations, parameter is reserved = 0
    Block_sizeShi __ViewController__viewDidLoad_block_impl_0size
struct __ViewController__viewDidLoad_block_impl_0 {
  struct __block_impl impl;
  struct __ViewController__viewDidLoad_block_desc_0* Desc;
  __ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
}

This should be seen impl corresponds Implements, see the name to know we can be understood as intended to declare a block corresponding class

  • struct __block_impl impl Is the "core classes" Our top description
  • struct __ViewController__viewDidLoad_block_desc_0* Desc block description, describes the amount of space Block_size block
  • __ViewController__viewDidLoad_block_impl_0 This constructor is a structure
  • void *fpThe first argument to the constructor function, execute the function pointers, assigned to implthe variable funcPtrpointer
  • struct __ViewController__viewDidLoad_block_desc_0 *descHere again, as the second argument to the constructor, assignment to Desca variable
  • int flags=0Ibid., Assigned to implthe Flagsvariable, but this is interesting, it defaults to 0, meaning Zijiu, because I can not. .
  • impl.isa = &_NSConcreteStackBlock;This corresponds also _NSConcreteGlobalBlock _NSConcreteMallocBlockhere we just need to know that it corresponds to the block on the stack, the other is behind us resolve
static void __ViewController__viewDidLoad_block_func_0(struct __ViewController__viewDidLoad_block_impl_0 *__cself) {
  NSLog((NSString *)&__NSConstantStringImpl__var_folders_t9_g3xrsv653kz2gr7tmgwfbfvh0000gn_T_ViewController_dd8c22_mi_0);
}
  • static void __ViewController__viewDidLoad_block_func_0Static block execution function, that is, we are {}in NSLogthat period.
  • struct __ViewController__viewDidLoad_block_impl_0 *__cself)Argument is that we just mentioned impl"core functional classes", but the strange thing is that it does not use the function body,
    which we can see behind the answer.
  • Middle would not have said, NSLog. .
WxsBlock blockObj = ((void (*)())&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA));
  • (void (*)())No anonymous marked the return value of the function pointer, and takes no arguments, and this is our corresponds to the front of the typedef void(*WxsBlock) ();block statement
  • & The address-of operator I am a bit ignorant force, to a great God understand C pointers about (ps: silently to see C textbook university ..), although can not read, but does not affect our overall interpretation.
  • __ViewController__viewDidLoad_block_impl_0Is __ViewController__viewDidLoad_block_impl_0a constructor structure, that is, we define a constructor of the block. Top with said parameters.
  • __ViewController__viewDidLoad_block_func_0Inside is NSLog...that the function pointer, which is what we wrote in the body of code logic block pointer.
  • __ViewController__viewDidLoad_block_desc_0_DATAIt is __ViewController__viewDidLoad_block_desc_0declared a description of the object is created

Block parameters to achieve

In the .m file:

typedef void(^WxsBlock) (NSString *str,NSArray *arr);

- (void)viewDidLoad {
    [super viewDidLoad];
    WxsBlock blockObj = ^(NSString *str,NSArray *arr){
        NSLog(@"test");
    };

    blockObj(@"wxs",[NSArray array]);
}

After clang compiled by:

typedef void(*WxsBlock) (NSString *str,NSArray *arr);

struct __ViewController__viewDidLoad_block_impl_0 {
  struct __block_impl impl;
  struct __ViewController__viewDidLoad_block_desc_0* Desc;
  __ViewController__viewDidLoad_block_impl_0(void *fp, struct __ViewController__viewDidLoad_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

static void __ViewController__viewDidLoad_block_func_0(struct __ViewController__viewDidLoad_block_impl_0 *__cself, NSString *str, NSArray *arr) {
  NSLog((NSString *)&__NSConstantStringImpl__var_folders_t9_g3xrsv653kz2gr7tmgwfbfvh0000gn_T_ViewController_cf62af_mi_0);
}

static struct __ViewController__viewDidLoad_block_desc_0 {
  size_t reserved;
  size_t Block_size;
} __ViewController__viewDidLoad_block_desc_0_DATA = { 0, sizeof(struct __ViewController__viewDidLoad_block_impl_0)};

static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
    ((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
    WxsBlock blockObj = ((void (*)(NSString *, NSArray *))&__ViewController__viewDidLoad_block_impl_0((void *)__ViewController__viewDidLoad_block_func_0, &__ViewController__viewDidLoad_block_desc_0_DATA));

    ((void (*)(__block_impl *, NSString *, NSArray *))((__block_impl *)blockObj)->FuncPtr)((__block_impl *)blockObj, (NSString *)&__NSConstantStringImpl__var_folders_t9_g3xrsv653kz2gr7tmgwfbfvh0000gn_T_ViewController_cf62af_mi_1, ((NSArray *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSArray"), sel_registerName("array")));
}

通过对比看出,我们加入了两个参数,编译出来的cpp代码和之前的对照也只是在传参的地方有所不同,在实现和逻辑调用上并没有发生变化。
Published 139 original articles · won praise 35 · views 410 000 +

Guess you like

Origin blog.csdn.net/wxs0124/article/details/65443448