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;

    }

        

  • 相关阅读:
    mysql 5.7修改密码
    使用zfs进行pg的pitr恢复测试
    什么是构造函数?它和普通函数的区别?
    匿名函数和普通函数的区别
    http缓存机制
    全局变量和局部变量
    什么是web语义化?
    ajax状态值和状态码
    如何理解MVVM?
    如果理解&&运算符和各类数值的布尔值
  • 原文地址:https://www.cnblogs.com/oumygade/p/4280779.html
Copyright © 2011-2022 走看看