码迷,mamicode.com
首页 > 其他好文 > 详细

block的内存分析,循环引用,变量访问,数据结构定义

时间:2015-02-11 18:01:46      阅读:530      评论:0      收藏:0      [点我收藏+]

标签:

 

一.block的内存分析

技术分享

 

 

 

如上图:

定义了一个weak的block,那么它在内存中的表现形式如右下角,

1.没有对block进行copy操作,而是weak,block就存储在栈空间中.

2.如果block存储于栈空间,不会对block内部所用到的对象产生强引用.

技术分享

 

 

如上图:

对block进行了一次copy操作,如果对block进行copy操作,block就会存储到堆空间当中.

1.如果block存储于堆空间,就会对block内部所用到的对象产生强引用.

2.如下图所示,就会产生循环引用,造成P对象无所释放,引发内存泄露

二.block的循环引用

解决办法为:

XqPersion *p = [XqPersion alloc] init];

__weak typeof(p) weakP = p;

或者用__unsafe_unretained typeof(p) weakP = p;

p.myBlock = ^{

  [p run];

}

 

而对于非ARC的解决办法为:

XqPersion *p = [XqPersion alloc] init];

__block typeof(p) weakP = p;

p.myBlock = ^{

  [p run];

}

[p release];

 

 三.block的变量访问

1.

int age  =10;

void (^block)() = ^{

  NSLOG(@"age = %d",age);

}

age = 20;

block();

输出结果为:10

void (^block)() = ^{

  NSLOG(@"age = %d",age);

}在声明这个block代码的时候,它已经把10放到了NSLOG(@"age = %d",10);以后这个地方就是一个常量10,可以称它为值捕获;

表面上看起来是age变量,但实际上它是把age的值10放进去了

相当于

void (^block)() = ^{

 

  NSLOG(@"age = %d",10);

 

}

 

无age的值怎么改变, block输出的都是10

 

2.

__block int age  =10;

void (^block)() = ^{

  NSLOG(@"age = %d",age);

}

age = 20;

block();

输出结果:20

当在前面声明__block时候,实际上传递的是age的地址 &age

在编译的时候block为:

void (^block)() = ^{

  NSLOG(@"age = %d",*(&age));

}

所有当下面age的值发生改变的时候 输出的block也相应发生改变; 

 

 

三.block的数据结构定义

 

一个block实例实际上由6部分组成:

struct Block _layout{

  void *isa;

  int flags;

  int reserved;

  void (*invoke)(void *,...);

  struct Block descriptor *descriptor;

};

1,isa指针,所有的对象都有该指针,用于实现对象相关的功能

2,flags,用于按bit位表示一些block的附加信息

3.reserved,保留变量

4.invoke,函数指针,指向具体的block实现的函数调用.

5.descriptor, 表示该block的附加描述信息

6.variables, capture过来的变量,block能够访问它外部的局部变量,就是因为将这些变量(或变量地址)复制到了结构体中.

 

在Object-C一共有3种类型的block

1,_NSConcreteGlobalBlock,全局的静态Block,不会访问任何的外部变量

2,_NSConcreteStackBlock,保存在栈中的Block,当函数返回时会被销毁

3,_NSConcreteMallocBlock,保存在堆中的Block,当引用计数器为0时会自动销毁

 

block的内存分析,循环引用,变量访问,数据结构定义

标签:

原文地址:http://www.cnblogs.com/xqios/p/4286504.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!