• iOS Block的内存管理


    1. Block实际上是指向结构体的指针,编译器会将内部的代码生成对应的函数

    2. Block内部使用了外部的变量, 内部是否能修改外部的变量,取决于外部变量是怎么给Block传值的:

      1>如果传的指针,就可以改;

      2>如果传的只是变量的数值,则不可以改.

    3. Block的内存管理:

      1>默认情况下,Block的内存在栈中,它不会对所引用的对象做任何操作

        Person *p = [[Person alloc]init];

        p.age = 20;

        void (^block)() = ^{

            NSLog(@"--block-%d",p.age);

        };

        block();

        [p release];

    打印: --block-20

        人被释放了

      2>对Block做一次copy操作,block的内存就会做一次retain操作:

        a>非ARC,如果所引用的对象,使用 __block修饰,就不会做retain操作

        b>ARC,如果所引用的对象,使用 __weak __unsafe_unretained 修饰,就不会做retain操作

        Person *p = [[Person alloc]init];

        p.age = 20;

        void (^block)() = ^{

            NSLog(@"--block-%d",p.age);

        };

        Block_copy(block);

        [p release]; //执行到改行,人不会释放, 修改代码:__block Person *p = [[Person alloc]init];就可以释放

      3>非ARC中,一个类的Block属性,如果想做到这个类的对象存在,Block就存在.则这个Block属性不能用assign,必须用copy

          a>因为Block的内存是在栈中,随时可能会被释放

        b>用copy的花,Block的内存在堆中,它的释放由程序员控制

        c>在类的- (void)dealloc方法中, 加上 Block_release(block块对象名);

               d>在init方法中,Block引用外部变量时,要注意避免循环retain

    #pragma mark - person.h

    @interface Person : NSObject

    @property (assign,nonatomic) NSInteger age;

    @property (copy,nonatomic) void (^myBlock)();

    @end

    #pragma mark - person.m

    #import "Person.h"

     @implementation Person

    - (void)dealloc

    {

        NSLog(@"人被释放了");

        Block_release(self.myBlock);

        [super dealloc];

    }

    @end

    #pragma mark - person.m

    - (id)init

    {

        if (self = [super init]) {

            self.myBlock = ^{

                NSLog(@"---%d",self.age); // 因为myBlock属性是copy类型,所以会对内部的self做retain

            };

        }

        return self;

    }

    #pragma mark - mainViewController.m

    Person *p = [[Person alloc]init]; 

    [p release]; //仅看这2行代码,看不出有内存泄露,内存泄露的问题是出在init方法内部

    正确的写法:

    #pragma mark - person.m

    - (id)init

    {

        if (self = [super init]) {

         __block typeof (self) p = self;

            self.myBlock = ^{

                NSLog(@"---%d",p.age); 

            };

        }

        return self;

    }

        

  • 相关阅读:
    [置顶] Guava学习之Lists
    Study notes for B-tree and R-tree
    uva 620 Cellular Structure
    [置顶] 程序员面试之道(《程序员面试笔试宝典》)之看着别人手拿大把的offer,不淡定了怎么办?
    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)
    有N个正实数(注意是实数,大小升序排列) x1 , x2 ... xN,另有一个实数M。 需要选出若干个x,使这几个x的和与 M 最接近。 请描述实现算法,并指出算法复杂度
    C# 未能加载文件或程序集“MySQLDriverCS..." 错误解决
    LA 3942 Remember the Word(前缀树&树上DP)
    原根-快速求解一个数的原根
    线程初步了解
  • 原文地址:https://www.cnblogs.com/oumygade/p/4280779.html
Copyright © 2020-2023  润新知