IOS使用Block —— 3 Block的两个注意点

首先普及一下内存存储区域知识:

内存分为五大区域:堆、栈、全局区、文字常量区、代码区

堆存放:由new、alloc分配的内存块,由程序员控制释放     p1 = (char *)malloc(10);

栈存放:存放函数参数、局部变量,在不需要的时候由编译器自动清除的变量存储区。   int b;   char s[] = “abc”;   char*p2;

全局区(静态):全局变量和静态变量存储放在一块的,程序结束后由系统释放

文字常量区:常量字符串放在这里,程序结束系统释放

代码区:存放函数体的二进制代码


1    block在MRC下的内存隐患

问题:

1 - 下面这段代码在ARC中是否存在问题?

不存在

2 - 下面这个代码在MRC中是否存在问题?

存在,设置block后,在合适的时间回调block,不希望block被释放,所以要对block进行copy

typedef void (^blockType)();
// 定义返回值是block类型的函数
blockType test() {
    int i = 5;
    blockType bb = ^{
          NSLog(@“xxxx i = %d”, i);
     }
     // return bb;   // 防止被释放,copy到堆区,所以需要改为  return Block_copy(bb);
     return Block_copy(bb);
}
int main() {
    @autoreleasepool {
          // 接收test的返回值
          blockType b1 = test();
          // 执行block
          b1();
          // MRC下copy到堆区一份,需要释放该block的控件,所以需要添加一句   Block_release(b1());
           Block_release(b1());
     }
}

  

2  block循环引用

发现问题:

控制器中对Block进行copy,copy后对block进行一个强引用,block中的self对控制器进行强引用,所以造成了一个强引用环,互相无法释放

解决问题:

打破强引用环只要将block中的 self 变成弱指针,即可解决;

// 这个神奇的方法就是:
__weak typeof(self) weakSelf = self;   // 将block中的self改为weakSelf

最后本人在查阅过程中翻过的帖子贴上:

——————内存————————

堆栈区别:http://blog.csdn.net/aixiaolin/article/details/6863991

区域划分:http://blog.csdn.net/wealoong/article/details/8686353

——————block————————

ARC与非ARC下block属性问题:http://www.mgenware.com/blog/?p=1493

容易引起“循环引用”的三种场景:http://www.2cto.com/kf/201409/332193.html

block使用测试:http://www.cocoachina.com/bbs/read.php?tid=152222&page=1

时间: 2024-08-16 03:11:54

IOS使用Block —— 3 Block的两个注意点的相关文章

IOS多线程之Block编程

1 什么是block iOS SDK 4.0開始,Apple引入了block这一特性.字面上说,block就是一个代码块.可是它的奇妙之处在于在内联(inline)运行的时候(这和C++非常像)还能够传递參数. 同一时候block本身也能够被作为參数在方法和函数间传递.这就给予了block无限的可能. 对于闭包(block),有非常多定义.当中闭包就是可以读取其他函数内部变量的函数,这个定义即接近本质又较好理解. 对于刚接触Block的同学,会认为有些绕,由于我们习惯写这种程序main(){ f

IOS开发之---初识Block

正文 Block简介 我们可以把Block当做Objective-C的匿名函数.Block允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观.另外,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息. Block的创建 实际上,block使用了与函数相同的机制:可以像声明函数一样,来声明一个bock变量:可以利用定义一个函数的方法来定义一个block:也可以将block当做一个函数来调用. 1 // main.m 2 #im

IOS学习之路--BLOCK

/* 1.定义block变量: 返回值类型 (^block变量名) (参数类型1, 参数类型2, ....); 2.给block变量赋值 block变量名 = ^(参数类型1 参数名称1, .....) { }; */ /* 1.设置动画属性 2.开始执行动画 3.动画执行完毕 block1 = ^{ 封装了动画开始执行前想做的事情 }; block2 = ^{ 封装了动画执行完毕后想做的事情 }; */ #import <Foundation/Foundation.h> //typedef

IOS开发- 用block实现回调

在IOS开发中经常会用到回调的情况,下面介绍如何用block实现回调. 1 #import <Foundation/Foundation.h> 2 3 @interface BLock : NSObject 4 5 + (void)getBlock:(void (^)(NSString *))someblock; 6 7 @end BLock.h 1 #import "BLock.h" 2 #import <Foundation/Foundation.h> 3

[转]iOS中ARC下Block的循环引用

[ARC的特性] ARC下,所有NSObject类型指针, 1. 默认为__strong类型 2. 可以显示的指定为__weak类型,__weak类型指针在所指向对象销毁后会自动置为nil 3. __autorelesing类型用于inout参数类型 ARC下,当一个函数返回一个NSObject指针时,编译器会帮我们实现autorelease调用.例如: return pObject; 编译器会帮我们扩展为 return [pObject autorelease]; ARC下,不能显式relea

iOS学习-9 - 1 .Block 入门

来自李明杰的视频. block 用来保存一段代码 block 的标志:^ block  跟函数很像: 1).可以保存代码  2).有返回值  3). 有形参 temp1:没有返回值.没有形参的 block 如果 block 没有形参,可以省略 () void(^myblock)() = ^{ NSLog(@"----------"); NSLog(@"----------"); }; // 利用 block 变量调用 block 内部的代码 myblock(); t

android/IOS常用图片上传的两种方式

android/IOS常用图片上传的两种方式: 1.上传到服务器的文件服务器(FileServer) 原理:上传到文件服务器的方式是先在服务器端搭建文件服务器,配置好路径(url),该路径是我们待会上传图片的路径,配置成功后便通过http+post的模式上传到文件服务器,同时文件服务器将返回一个图片ID,这个ID就是图片的唯一标识,并将该ID写入数据库保存,当需要下载该图片时只需要将此ID带上即可. 两个核心问题: (1)服务端:配置FileServer,并写处理响应上传图片的代码,这个值得去网

Block实现-block存储域

Block转换为Block的结构体类型的自动变量,_block变量转换为_block变量的结构体类型的自动变量,所谓结构体类型的自动变量,即栈上生成的该结构体的实例.我们已经了解了block时oc对象,该block的类为_NSConcereteStackBlock,虽然该类并没有出现以变换源代码中,还有很多类似的类 _NSConcereteStackBlock    对象存储域在栈上 _NSConcereteGlobalBlock     域全局变量一样,设置在程序的数据区域(.data中) _

block 解析 - block变量

block变量 上一篇 讲的是block静态变量的特性,这里我们来看一下_block变量.引用官方: You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __blockstorage is similar to, but mutually exclusive of, the register, auto, a

ios给NSMutableDictionary循环赋值的两种方式,在循环内初始化NSMutableDictionary和在循环外初始化NSMutableDictionary有何区别?(已解决)

NSMutableArray * arrayName = [NSMutableArray array]; NSMutableArray * array = [NSMutableArray array]; [array removeAllObjects]; for (int i = 0; i< 10; i++) { NSString * str = [NSString stringWithFormat:@"name%i",i]; [arrayName addObject:str];