ios

block 属性用什么修饰

2020-05-13  本文已影响0人  Shirly_you

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
image.png

当 block 内部引入外部变量的时候:

  1. MRC不管它用什么类型修饰,retain修饰会在栈区, copy修饰在堆区,使用 copy 修饰,会将栈区的 block 拷贝到堆区.
  2. 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


image.png

ARC


image.png

ARC情况下,retain实际是对应的strong,所以也在堆区.

上一篇下一篇

猜你喜欢

热点阅读