美文网首页iOS 面试
#1-对于block的理解,mrc和arc的区别

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

作者: iRemark | 来源:发表于2018-08-02 09:33 被阅读0次

    block在ARC和MRC中的声明引用有些区别:

     block可以存储在栈中,也可以在堆中
     默认存储在栈中,不需要管理内存
     存储在堆中的block会对block进行retain操作
    

    copy使栈中的block转移到堆中,并对block会引用的对象进行retain操作
    block在堆中时,不想block对引用的对象进行retain操作

    • (MRC)前面加__block
    • (ARC)前面加__weak
      引用就变成了弱引用,retainCount 不会 +1
    1.dog.h (NSObject类)

    //block用copy来定义,这样block存在于堆中
    //如果block不是copy到堆中,引用完了对象还在,但block被释放了

     #import <Foundation/Foundation.h>
    @interface dog : NSObject
    @property (nonatomic, assign) int age;
    @property (nonatomic, copy) void (^myBlock)();
    
    2.dog.m

    引用self.age会使retainCount = 2的
    因此以__block typeof(self) mySelf = self;方式重新定义self 避免循环引用

    #import "dog.h"
    @implementation dog
    - (instancetype)init {  
      if (self = [super init]) {
            self.age = 10;
            self.myBlock = ^{
                NSLog(@"%d",mySelf.age);
            };
        }
      return self;
    }
    
    - (void)dealloc {
           NSLog(@"dog - dealloc");
          //对定义时copy的block进行释放
           Block_release(self.myBlock);
           [super dealloc];
    }
    
    3.main.m文件
    int main(int argc, const char * argv[]) {
        //3.1 block在ARC和MRC中的情况
        blockARC_MRC();
        //3.2 copy block情况
        copyBlock();    
        return 0;
    }
    

    void blockARC_MRC(){
        __block dog *d = [[dog alloc] init];
        d.age = 12;
        NSLog(@"block引用前:d retainCount = %zd",d.retainCount);
        void (^myBlock)() = ^() {
                NSLog(@"d.age = %d",d.age);
        };
        NSLog(@"block引用后:d retainCount = %zd",d.retainCount);
    
        Block_copy(myBlock);
        NSLog(@"block copy后:d retainCount = %zd",d.retainCount);
        Block_release(myBlock);
        NSLog(@"block release后:d retainCount = %zd",d.retainCount);
        myBlock();
        NSLog(@"block调用后:d retainCount = %zd",d.retainCount);
    
      [d release];
    }
    
    • block中引用成员变量情况
     void copyBlock() {
        __block dog *d = [[dog alloc] init];
        d.age = 12;
        NSLog(@"block引用前:d retainCount = %zd",d.retainCount);
        d.myBlock = ^{
              NSLog(@"myBlock -- %d",d.age);
        };
        NSLog(@"block引用后:d retainCount = %zd",d.retainCount);
        d.myBlock();
        NSLog(@"block调用后:d retainCount = %zd",d.retainCount);
    
      [d release];
    }
    

    相关文章

      网友评论

        本文标题:#1-对于block的理解,mrc和arc的区别

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