zoukankan      html  css  js  c++  java
  • 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;

    }

        

  • 相关阅读:
    性能百万/s:腾讯轻量级全局流控方案详解
    Swagger2
    shiro 入门
    01、单例模式
    02、工厂方法
    04、模板模式
    13、Adapter 适配器
    14、迭代器
    Java 面向切面 AOP
    spring boot 中使用 Redis 与 Log
  • 原文地址:https://www.cnblogs.com/oumygade/p/4280779.html
Copyright © 2011-2022 走看看