arc 中block 知多少?

作者: LeeDev | 来源:发表于2016-07-06 10:47 被阅读237次

**1.block 分配的地址 **
block 大概可以分配到3个地方
NSGlobalBlock(全局的)、NSMallocBlock(堆中)、NSStackBlock(栈中)

**2.下面写个demo详细介绍上面的3个点 **

//
//  ViewController.m
//  strong weak 的用法
//
//  Created by apple on 16/7/5.
//  Copyright © 2016年 李重阳. All rights reserved.
//

#import "ViewController.h"


@interface ViewController ()

@property (nonatomic,assign) int  add;

@property (nonatomic,weak) void(^block1)(int);
@property (nonatomic,weak) void(^block2)();
@property (nonatomic,weak) void(^block3)();

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.add = 1;
    __weak typeof(self) weakSelf = self;
    
/*-------------------1.全局的block-----------------------------------------**/
    /*1.全局的block**/
    /* 只是操作自己的参数 不能操作其他任何的参数 **/
    
    void (^block)(int) = ^(int a) {
        
        NSLog(@"block1:%d", a);
    };
    NSLog(@"block1_type = %@",block);//block1_type = <__NSGlobalBlock__: 0x10a1be0e0>
    
/*-------------------2.分配到堆中的block--------------------------------**/
    /*
     * 2.分配到堆中的block
     * 会分配到堆中的block
     * 即在arc中默认会将block从栈复制到堆上(arc 中 默认是 __strong 修饰),
     * 而在非arc中,则需要手动copy.
     * 在arc 中如果 block 中引用了其他的变量 (不管是局部变量还是全局变量),都会拷贝到堆中
     **/
    
    void (^block2)(void) = ^{
        
        /*1).这种情况调用的时候还是崩溃**/
        //NSLog(@"block2:%d", weakSelf.add);
        
        /*2).这种情况调用的时候还是崩溃**/
//        __strong ViewController * strongSelf = weakSelf;
//        NSLog(@"block2:%d", strongSelf.add);
        
        /*3).这种情况调用的时候还是崩溃**/
        //NSLog(@"block2:%d", self.add);
        
        NSLog(@"block2:%@", self);
        /*
         * 上面的情况调用崩溃,很可能是 block2 在viewdidLoad 结束后 ,又马上释放掉了
         * 但是有个疑问就是 怎么block 里面引用了self 还是不行了呢?
         * 在touchesBegan中打印了 self.block2 的值 = null,说明的是 当前的block2 在
         * 在viewdidLoad 结束后会马上的释放掉 并且block = nil (所以里面的不管copy 了多少东西都马上清空了);
         * 只有全局的block 还是 还是能看到地址
         * 栈block 直接崩溃(可能是栈里面的东西 ios 系统没做处理,释放后没有让其值 = nil)
         ***/
        
    };
    NSLog(@"block2_type = %@",block2);//block2_type = <__NSMallocBlock__: 0x7fa9c2418d90>
    

    
/*-------------------3.分配到栈中block--------------------------------**/
    /*
       3.分配到栈中(用__weak 来修饰) ,
       这个当在 其他地方调用的时候 很容易崩溃
     **/
    __weak void (^block3)(void) = ^(){
        
        NSLog(@"block3:%d", weakSelf.add);
    };
    NSLog(@"block3_type = %@",block3);//block3_type = <__NSStackBlock__: 0x7fff50da8980>
    
    
/*-------------------4.测试 --------------------------------**/
    /*
     * 测试 
     * 我们用一个weak 的全局block 来引用
     * 在touchBegan 中调用
     **/
    
    self.block1 = block;
    self.block2 = block2;
    self.block3 = block3;
    
    /* 
      在viewdidLoad 里面 都可以 正常的执行 ,但是在touchesBegan: 中就可能出现问题
     **/
    self.block1(1);//正常运行
    self.block2();//正常运行
    self.block3();//正常运行
    
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    
    NSLog(@"self.block1 = %@",self.block1);//<__NSGlobalBlock__: 0x102baf0f0>
    NSLog(@"self.block2 = %@",self.block2);//(null)
    //NSLog(@"self.block3 = %@",self.block3);//直接崩溃
    
    
    //self.block1(1);//正常运行
    
    //self.block2();//直接崩溃
    
    //self.block3();//直接崩溃
}


@end


**3.总结 **
1).关于 __weak typeof(self) weakSelf = self;
在block中 __strong ViewController * strongSelf = weakSelf;主要用在第三方的block 中,解释说,是为了防止block 提前释放,同时防止循环引用 ,很想 求一个例子,不写这个和写这个出现不同的结果。到目前为止 我个人理解是没用,没效果(真的很希望求一个例子)。
2)block中 还是用strong 或者copy 拷贝到堆中,不要让其马上释放掉
3)后续 在研究一下block

相关文章

  • arc 中block 知多少?

    **1.block 分配的地址 **block 大概可以分配到3个地方NSGlobalBlock(全局的)、NS...

  • arc 中block知多少(2)?

    1.参数block 当做参数的block ,如果参数没有引起到其他的值的话,是全局的block,但当引用到了值的话...

  • block 在ARC下对变量的影响

    在ARC :Block访问外部的变量 ARC环境下,当单纯定义一个block存储在全局区 ARC环境下,block...

  • ARC中的block

    三大类型 NSGlobalBlock: 位于内存静态全局区。没有调用任何变量或者调用的为全局变量、静态变量。你可以...

  • 面试题整理

    3. __block在arc和非arc下含义一样吗? 是不一样的。 在MRC中block variable在blo...

  • Blcok相关经典面试题

    题目:事例分析Block在ARC和MRC情况下的使用。 ARC与MRC在Xcode中的切换:arc-->mrc 更...

  • #1-对于block的理解,mrc和arc的区别

    block在ARC和MRC中的声明引用有些区别: copy使栈中的block转移到堆中,并对block会引用的对象...

  • block 的修饰符

    _block & _weak: ARC下 在block代码块中也会用类似代码来修饰变量,例如:__weaktype...

  • __weak & __block

    1.__block:可以在ARC、MRC下使用 __weak:只能在ARC下使用 2.__block:可以修饰对象...

  • iOS - ARC环境下dealloc/didReceiveMe

    block没那么难(三):block和对象的内存管理 一、iOS开发 ARC下dealloc的使用 ARC下,系统...

网友评论

    本文标题:arc 中block 知多少?

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