0%

block相关的修饰符

__weak修饰符

__weak修饰对象时和废弃对象时的调用流程

__weak修饰对象时和废弃对象时的调用流程

__block说明符

原始代码

1
2
3
4
5
6
7
8
9
#import <Foundation/Foundation.h>
int main(int argc, char const *argv[])
{
__block int a = 1;
^{
a ++;
};
return 0;
}

经clang编译后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};


struct __Block_byref_a_0 {
void *__isa;
__Block_byref_a_0 *__forwarding;
int __flags;
int __size;
int a; // 最后一个成员变量相当于源自动变量的成员变量
};

struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_a_0 *a; // by ref
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_a_0 *_a, int flags=0) : a(_a->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
__Block_byref_a_0 *a = __cself->a; // bound by ref

(a->__forwarding->a) ++;
}

static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->a, (void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->a, 8/*BLOCK_FIELD_IS_BYREF*/);}

static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
void (*dispose)(struct __main_block_impl_0*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

int main(int argc, char const *argv[])
{
// __block 变成了__Block_byref_a_0结构体类型的自动变量,既在栈上生成的__Block_byref_a_0结构体实例,命名规则:__Block_byref_变量名_出现的顺序
__attribute__((__blocks__(byref))) __Block_byref_a_0 a = {
(void*)0,
(__Block_byref_a_0 *)&a,
0,
sizeof(__Block_byref_a_0),
1 // 初始值为1
};

((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344));
return 0;
}

__block变量和对象

1
2
3
4
5
6
7
#import <Foundation/Foundation.h>
int main(int argc, char const *argv[])
{
__block id obj = [[NSObject alloc] init];
// ARC下等同 __block id _strong obj = [[NSObject alloc] init];
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
当block从栈上复制到堆上时,使用_Block_object_assign函数,持有Block截获的对象
当堆上的Block被废弃时,使用_Block_object_dispose函数,释放Block截获的对象
*/

// __block变量声明部分
struct __Block_byref_obj_0 {
void *__isa;
__Block_byref_obj_0 *__forwarding;
int __flags;
int __size;
void (*__Block_byref_id_object_copy)(void*, void*);
void (*__Block_byref_id_object_dispose)(void*);
__strong id obj;
};

int main(int argc, char const *argv[])
{
// __block 变量赋值部分
__attribute__((__blocks__(byref))) __Block_byref_obj_0 obj =
{
(void*)0,
(__Block_byref_obj_0 *)&obj,
33554432,
sizeof(__Block_byref_obj_0),
__Block_byref_id_object_copy_131,
__Block_byref_id_object_dispose_131,
((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"))};

return 0;
}