How to block is achieved
We clang compiled Objective-C correspond to documents cpp file, to see his implementation, comparison of different styles of block
different,
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 thatint 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 reservedvoid *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_0
Look at the name, which is used to describe a block of,
size_t reserved
Reserved spacesize_t Block_size
block of space__ViewController__viewDidLoad_block_desc_0_DATA
Structure variable declarations, parameter isreserved = 0
Block_size
Shi__ViewController__viewDidLoad_block_impl_0
size
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 descriptionstruct __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 structurevoid *fp
The first argument to the constructor function, execute the function pointers, assigned toimpl
the variablefuncPtr
pointerstruct __ViewController__viewDidLoad_block_desc_0 *desc
Here again, as the second argument to the constructor, assignment toDesc
a variableint flags=0
Ibid., Assigned toimpl
theFlags
variable, but this is interesting, it defaults to 0, meaning Zijiu, because I can not. .impl.isa = &_NSConcreteStackBlock;
This corresponds also_NSConcreteGlobalBlock
_NSConcreteMallocBlock
here 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_0
Static block execution function, that is, we are{}
inNSLog
that period.struct __ViewController__viewDidLoad_block_impl_0 *__cself)
Argument is that we just mentionedimpl
"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 thetypedef 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_0
Is__ViewController__viewDidLoad_block_impl_0
a constructor structure, that is, we define a constructor of the block. Top with said parameters.__ViewController__viewDidLoad_block_func_0
Inside isNSLog...
that the function pointer, which is what we wrote in the body of code logic block pointer.__ViewController__viewDidLoad_block_desc_0_DATA
It is__ViewController__viewDidLoad_block_desc_0
declared 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代码和之前的对照也只是在传参的地方有所不同,在实现和逻辑调用上并没有发生变化。