__block:解决block循环引用
1.__weak
2.__block。 记住置为nil
3.block作为参数
self.block = ^(view controller *vc) {
nslog (self.name)
}。///> 保存函数代码块
self.block(self); ///> 执行方法
4.为什么有问题 0x7 栈区
5.block是一个结构体对象
6.自动捕获变量 a
1.面试题. 截获变量
int multiplier = 6;
int (^Block)(int) = ^int(int num) {
return num * multiplier;
};
multiplier = 4;
NSLog(@"result is %d",Block(2)); 12
局部变量 -->. 基本数据变量。对象类型
静态局部变量
全局变量
静态全局变量
block截获的 使用前的数据
对于基本数据类型 的局部变量 截获其值
对于 对象类型的局部变量 连同所有权修饰符一起截获
static int multiplier = 6;
int (^Block)(int) = ^int(int num) {
return num * multiplier;
};
multiplier = 4;
NSLog(@"result is %d",Block(2)); 8
2.__block
__block. 指针传递。 可以修改值
没有 __block。值传递
对 截获变量进行赋值操作时需要 使用。 __block
NSMutableArray *array = [NSMutableArray array];
NSMutableArray *array1 = [NSMutableArray array];
[array addObject:@"1"];
void(^block)(void) = ^ {
NSLog(@"array:%@ array1:%@",array,array1);
};
[array addObject:@"2"];
array1 = @[@"2234234234",@"2342342"].mutableCopy;
block();
内部保存的是array之前的指针 array1 之后的指针发生了变化
/*
array:(
1,
2
) array1:(
)
*/
没有赋值 不要使用__block
对静态变量。全局变量 静态全局变量。不需要使用__block
__block int multiplier = 6; 指针
int (^Block)(int) = ^int(int num) {
return num * multiplier;
};
multiplier = 4;
NSLog(@"result is %d",Block(2)); 8
3.Block的内存管理
Block_copy()必须与相应的Block_release() MRC下才可以使用
ARC下直接使用copy
NSInteger interI = 10;
NSInteger i = 10;
block = [^{
NSLog(@"%ld", interI);
} copy];
4.Block的原理是什么?本质是什么
Block 本身也有一个isa指针 说明Block也是一个OC对象
封装了代码块。合适的时候执行
本身保存了 函数执行的地址。还有我们需要的参数
为什么局部变量需要捕获参数 到 block里面
因为是跨函数访问。 到另外一个函数里面就访问不到了。但是全局的事可以访问的
局部变量: auto。值访问。 会销毁
static。指针访问
5.Block的类
NSLog(@"%@",[block class]);
NSLog(@"%@",[[block class] superclass] );
NSLog(@"%@",[[[block class] superclass] superclass]);
NSLog(@"%@",[[[[block class] superclass] superclass] superclass]);
2019-06-24 22:23:56.751697+0800 OC-Test[96730:11558820] __NSMallocBlock
2019-06-24 22:23:56.751733+0800 OC-Test[96730:11558820] NSBlock
2019-06-24 22:23:56.751780+0800 OC-Test[96730:11558820] NSObject
// 堆:动态分配内存,需要程序员申请申请,也需要程序员自己管理内存
void (^block1)(void) = ^{
NSLog(@"Hello");
};
int age = 10;
void (^block2)(void) = ^{
NSLog(@"Hello - %d", age);
};
NSLog(@"%@ %@ %@", [block1 class], [block2 class], [^{
NSLog(@"%d", age);
} class]);
__NSGlobalBlock__ 放在数据段里面
__NSMallocBlock__ 堆区
__NSStackBlock__ 栈区
没有访问auto变量的block是__NSGlobalBlock __ ,放在数据段
访问了auto变量的block是__NSStackBlock __
[__NSStackBlock __ copy]操作就变成了__NSMallocBlock __
在ARC环境下,编译器会根据情况自动将栈上的block复制到堆上的几种情况?
1.block作为函数返回值时 【使用了auto变量的时候】
2.将block赋值给__strong指针时
3.block作为Cocoa API中方法名含有usingBlock的方法参数时
4.block作为GCD API的方法参数时
栈空间的block是不会强引用 外面的 auto对象的
堆空间的block如果 如果是强引用那么里面也会强引用
网友评论