//https://www.jianshu.com/p/d28a5633b963
#import <Foundation/Foundation.h>
void (^FFGlobalBlock)(void) = ^{
NSLog(@"111");
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
FFGlobalBlock();
// NSGlobalBlock NSMallocBlock NSStackBlock(在ARC下基本不可能出现)
NSLog(@"%@", [FFGlobalBlock class]);
// 在函数内定义,但是Block没有引用外部变量,故是 NSGlobalBlock
void(^FFGlobalBlock2)(void) = ^{
NSLog(@"222");
};
FFGlobalBlock2();
NSLog(@"%@", [FFGlobalBlock2 class]);
/// 在ARC下,自动生成将block从Stack上复制到Malloc上的代码。
/// 这些情况下栈上的代码将copy到malloc上。
/// 调用Block的Copy方法。
/// 将Block作为函数的返回值。
/// 将Block复制给__strong修饰的变量时。
/// 向cocoa框架中含有usingBlock的方法或者GCD的API传递Block参数时。
/// RAC下对象的默认修饰符是 automic readwirte Strong 此时在ARC下是 NSMallockBlock。 在MRC下是 NSStackBlock。
/// Block会截获自动变量。会在block中复制一份只想该变量的指针。故不能修改值,但如果是对象的话可以对对象里的属性进行操作,如果是Person实例,不能修改这个实例,但是可以修改他的属性,即更改Person的Name,age等。
/// __block修饰的自动变量可以进行修改是因为 将__block修饰的自动变量封装成立一个结构体放在malloc上,以便从栈上或堆上访问和修改同一份数据。
int i = 3;
void(^FFMallocBlock)(void) = ^{
NSLog(@"%d", i);
};
/// 如果想修改的话,用__block修饰block
i = 5;
FFMallocBlock();
NSLog(@"%d", i);
NSLog(@"%@", [FFMallocBlock class]);
NSLog(@"---%@", [^{NSLog(@"%d", i);} class]);
}
/// 避免block的循环引用的三种方法。
/// 1: 使用__weak修饰。通常与__strong配合使用
/// 2: 使用__block修饰。问题,必须调用一次,并且要置为nil 否则存在内存泄漏。
// __block XXViewcontroller *weakSelf = self;
// self.blk = ^{
// NSLog(@"%@", weakSelf);
// weakSelf = nil;
// }
/// 3: 以参数的形式传入。可以避免
// self.block = ^(ViewController *vc){
// NSLog(@"%@", vc.name);
// }
return 0;
}