美文网首页
weak指针指向stackBlock并不会随stackBlock

weak指针指向stackBlock并不会随stackBlock

作者: 孙小猴猴猴 | 来源:发表于2019-04-15 00:20 被阅读0次

    · 前言

    无意中写的demo遇到了这个问题,引出了block的三种类型以及编译器在ARC环境下对block进行优化的知识点,让自己对block以及ARC的内存管理有了更深刻的印象,特此写下来给需要帮助的iOSCoder

    · 问题描述

    如下所示,在一个UIButton中,我用了一个weak指针和一个strong指针接收一个block,在clickActionHandle方法执行block之前,将strong指针置为nil。

    理想情况:随着strong指针的销毁,weak指针也会随之置为nil而不执行block。

    实际情况:weakCCBack发生坏内存访问崩溃

    #import "CallBackButton.h"
    
    @interface CallBackButton ()
    
    @property (nonatomic,weak) void(^weakCCBack)(void);
    
    @property (nonatomic,strong) void(^strongCCBack)(void);
    
    @end
    
    @implementation CallBackButton
    
    -(instancetype)initWithCallBack:(void(^)(void))callBack{
        if (self = [super init]) {
            self.strongCCBack = callBack;
            self.weakCCBack = callBack;
            NSLog(@"self.strongCCBack = %@ self.weakCCBack =%@",self.strongCCBack,self.weakCCBack);
            [self addTarget:self action:@selector(clickActionHandle) forControlEvents:UIControlEventTouchUpInside];
        }
        return self;
    }
    
    -(void)clickActionHandle{
        self.strongCCBack = nil;
        if (self.weakCCBack != nil) {
            self.weakCCBack();
            self.strongCCBack = nil;
        }
    }
    
    

    · 原因解释

    同时用一个weak指针和一个strong指针指向init方法传过来的block时,当strong指针置为nil后,weak指针没有自动置为nil导致执行clickActionHandle方法时,发生了坏内存访问的错误。打印了两个指针的地址才发现时ARC对block的赋值进行了优化。

    self.strongCCBack = <__NSMallocBlock__: 0x600002617b40>
    
     self.weakCCBack =<__NSStackBlock__: 0x7ffee6405200>
    
    callBack = <__NSStackBlock__: 0x7ffee6405200>
    

    ·使用strong指针接收栈类型的block,编译器会将栈block进行一次拷贝操作生成一个新的堆Block保存在strong指针中。这么做的原因很容易理解:因为存储在栈中的值出了作用域以后会被系统自动回收,而block是一个等待着被执行的代码块,如果init方法结束后参数中的block(此block为栈block)会被立即回收,那么在执行block的时候会发生坏内存访问的情况,为了保证安全执行block,strong指针指向stackBlock(栈)的时候会生成一个mallocBlock(堆)副本,以确保能安全执行block。
    ·而使用weak指针指向栈block时,编译器未做任何优化,即便栈block被回收,weak指针也不会指向nil,继而导致执行block的时候会产生坏内存访问。

    相关文章

      网友评论

          本文标题:weak指针指向stackBlock并不会随stackBlock

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