Xcode 中设置 MRC 的开关:
1、全局设置:TARGETS → Build Settings → Apple Clang - Language - Objective-C → Objective-C Automatic Reference Counting 设为 No;(ARC 对应的是 Yes)
2、局部设置:TARGETS → Build Phases → Compile Sources → 找到需要设置的文件 → 在对应的 Compiler Flags 中设置 -fno-objc-arc。(ARC 对应的是 -fobjc-arc)
总结:
当 block 内部没有引入外部变量的时候,不管它用什么类型修饰,block 都会存在全局区
@interface ViewController ()
@property (nonatomic, strong) void (^strongBlock)(void);
@property (nonatomic, copy) void (^copyBlock)(void);
@property (nonatomic, retain) void (^retainBlock)(void);
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setCopyBlock:^{
}];
[self setStrongBlock:^{
}];
[self setRetainBlock:^{
}];
NSLog(@"StrongBlock: %@", _strongBlock);
NSLog(@"CopyBlock: %@", _copyBlock);
NSLog(@"RetainBlock: %@", _retainBlock);
}
@end
当 block 内部引入外部变量的时候:
- MRC不管它用什么类型修饰,retain修饰会在栈区, copy修饰在堆区,使用 copy 修饰,会将栈区的 block 拷贝到堆区.
- ARC下引入了weak strong,用strong、 copy修饰的都在堆区,所以用copy strong都可以,为什么strong修饰的也在堆区呢? 反汇编发现strong也具有copy的特性. 平常使用都用copy修饰,主要是strong是ARC时期引入的,开发者早已在MRC中习惯使用copy来修饰block.
- (void)viewDidLoad {
[super viewDidLoad];
//MRC
int x = 0;
[self setCopyBlock:^{
NSLog(@"%d", x);
}];
[self setStrongBlock:^{
NSLog(@"%d", x);
}];
[self setRetainBlock:^{
NSLog(@"%d", x);
}];
NSLog(@"StrongBlock: %@", _strongBlock);
NSLog(@"CopyBlock: %@", _copyBlock);
NSLog(@"RetainBlock: %@", _retainBlock);
}
MRC
ARC
ARC情况下,retain实际是对应的strong,所以也在堆区.