美文网首页
block的修饰词为什么选用copy

block的修饰词为什么选用copy

作者: 继续向前冲 | 来源:发表于2018-07-31 15:31 被阅读39次

    想必很多开发人员知道一般用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<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        //注意:MRC环境下:demoBolck1用assign,retain修饰,栈区:<__NSStackBlock__: 0x7fff50915a50>,提前释放了所以运行到下面语句程序会崩溃。ARC环境下:用copy,strong, assign, retain修饰是可以正常打印出结果的。 无论什么环境,用copy,strong修饰是可以正常打印出结果的
        
        self.demoBolck1();
        
    }
    

    转载:原文

    相关文章

      网友评论

          本文标题:block的修饰词为什么选用copy

          本文链接:https://www.haomeiwen.com/subject/xpdhvftx.html