美文网首页
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

    · 前言 无意中写的demo遇到了这个问题,引出了block的三种类型以及编译器在ARC环境下对block进行优化...

  • HOOK block

    block分为三种: globalblock stackblock mallocblock

  • Block的存储域

    1. StackBlock 2. Global Block 注意:GlobalBlock是全局Block,不需要截...

  • OC--看objc源码认识weak

    weak修饰有什么用? 声明为weak的指针,weak指针指向的对象一旦被释放,weak的指针都将被赋值为nil ...

  • 内存管理面试题

    1.weak实现原理当一个对象被weak指针指向时,这个weak指针会以对象为key存储到一个weak指针数组里面...

  • Objective - C block(三)block的copy

    (一)copy ARC环境下,编译器会根据情况自动将stackblock进行copy操作,复制到堆上 block作...

  • @property关键字

    1.weak: weak,弱指针,不会让引用计数器+1,如果指向对象被销毁,指针会自动置nil weak原理: r...

  • 2020-09-28 技术回顾

    weak的实现原理 Runtime 维护了一个 weak表,用于存储指向某个对象的所有weak指针。weak表 其...

  • dailyLearning -- 关键字weak实现原理

    weak 实现原理的概括 Runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其...

  • #2-weak 实现原理

    weak 实现原理的概括 Runtime维护了一个weak表,用于存储指向某个对象的所有weak指针。weak表其...

网友评论

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

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