block的修饰词为什么选用copy

想必很多开发人员知道一般用copy修饰block,接下来就讲解为什么需要用copy,甚至会讲到其实用strong修饰block也是可以的

在 Objective-C 语言中,一共有 3 种类型的 block:

_NSConcreteGlobalBlock 全局的静态 block,不会访问外部局部变量(显然包括无外部变量或者全局变量)。
_NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。
_NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。

@interface ViewController ()
@property (nonatomic,copy)void(^demoBolck)();

@property (nonatomic,strong)void(^demoBolck1)();
@end

@implementation ViewController

int b=8;//全局变量

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    void (^demoBolck)() = ^{
        
        NSLog(@"indemoBolck");
        
    };
    
    NSLog(@"demoBolck %@",demoBolck);    //<__NSGlobalBlock__: 0x1085af0e0>  无论ARC还是MRC下,因不访问外部局部(包括无外部变量或者只有全局变量),NSGlobalBlock表示在全局区
    
    void (^demoBolck4)() = ^{
        
        NSLog(@"indemoBolck4  %d",b);
        
    };
    
    NSLog(@"demoBolck4 %@",demoBolck4);    //<__NSGlobalBlock__: 0x10150b120>  全局区
    
    __block int a = 6;   //block内部引用a,并修改其值,需要用block修饰,不然可以不用
    
    void (^demoBolck2)() = ^{
        
        NSLog(@"indemoBolck2 %d",a++);
        
    };
    
    demoBolck2();
    
    NSLog(@"demoBolck2 %@,%d",demoBolck2,a);   //<__NSMallocBlock__: 0x600000056c50> ARC下堆区,在ARC模式下,系统也会默认对Block进行copy操作,Block的内存地址这时候便显示在堆区 <__NSStackBlock__: 0x7fff5d0ada28>MRC下在栈区
    
    NSLog(@"demoBolck2.Copy %@",[demoBolck2 copy]);    //<__NSMallocBlock__: 0x600000056c50>copy操作不管MRC或者ARC都在堆区,只是在MRC下进行copy会改变地址
    
    self.demoBolck = demoBolck2;
    
    NSLog(@"self.demoBolck %@",self.demoBolck);//堆区<__NSMallocBlock__: 0x608000052630>
    
    self.demoBolck1 = demoBolck2;
    
    self.demoBolck1();     //demoBolck2  7   能执行无问题
    
    NSLog(@"self.demoBolck1 %@",self.demoBolck1);     //<__NSMallocBlock__: 0x600000056c50>  strong修饰ARC和MRC都并没有问题, 但是assign和retain在MRC环境下是还是在栈区的,会有问题
    
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    
    //注意:MRC环境下:demoBolck1用assign,retain修饰,栈区:<__NSStackBlock__: 0x7fff50915a50>,提前释放了所以运行到下面语句程序会崩溃。ARC环境下:用copy,strong, assign, retain修饰是可以正常打印出结果的。 无论什么环境,用copy,strong修饰是可以正常打印出结果的
    
    self.demoBolck1();
    
}

转载:原文

你可能感兴趣的:(block的修饰词为什么选用copy)