Block控制器传值和内存泄漏

Posted 三更小新

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Block控制器传值和内存泄漏相关的知识,希望对你有一定的参考价值。

1BlockC语言的,是一种数据类型。Block出现后,很多代理都会被替代。Block是一种数据类型,是提前准备好的代码段,在需要的时候执行。其实就像调用一个函数一样。准备代码就是{},执行就是();

2Block常见问题:

*在定义Block时,如果引用了外部变量,会对外部变量做一次copy,记录住定义block时候变量的值,如果后续这个变量变了,也不会影响block的变化,这一瞬间是几就是几

*默认情况下不允许Block修改外部变量,因为拷贝是const拷贝。因为Block可以当一个函数,不应该破坏外部细节(就像NSString用copy一样不可变)

*如果要修改外部变量,用__block 修饰。不过修饰后,这个变量的地址永久变成了堆区了(不加__block修饰的,是一个栈一个堆,是两个地址,所以没法改)。

*如果访问的外部变量是一个OC对象(NSString Person*),那么其实只是拷贝到堆区的只是 这个OC对象在栈区的指针(*p),指针指向的内容还是在堆区的内容,没有变,唯一变的只是指针的地址,而不是指针指向的地址。此时,修改NSString的内容,其实没事!因为Block拷贝的是指向这个内容的地址。

3Block的应用场景:

*当做参数:用的很多。

*当做返回值:需要先定义这个返回值类型的Block(TypedefBlock),这一步类似定义了int,然后再声明。当做返回值用的比较少,用于框架比较多。

*控制器/自定义视图传值回调 异步任务回调。

4)多个控制器反向传值:

*代理:我传递数据的话,我写@propertyDelegate,我写协议,你遵守我,我给你值。

*Block:我传递数据的话,我写@propertyBlock,我写Block,我来调用Block(),你来填充Block的内容(就是代理的实现,只是写在了一起)。

如果回调方法比较少,一个方法里,有三个以内的block就差不多可以了,如果很多还是用代理吧。Block的好处就是所有代码都在一起,便于维护,好多在一起反而不好了。例如UITableView的代理方法有小20个,数据源方法也有10多个,像这种分工明确,回调多,但是不需要每一个方法都必须事件,这时候就用代理。

Block和代理都需要判断是否执行。Block如果不判断,对方没有实现Block内容的话,就会野指针EXC_BAD_ACCESS,因为找方法找不到。

5Block的循环引用:__weak *weakSelf = self;

/**

 block的陷阱-有可能会出现循环引用

 解决办法:

 1. 要对内存对象之间的引用关系要清楚

 技巧:

 1. 在block中碰到self,要格外小心,有可能会出现循环引用,通常最好思考一下

 2. 利用dealloc协助判断!如果不能被正常释放就说明有循环引用!

 */

6UINavigationControllers有个ViewControllers属性,这个其实是栈处理器。说白了就是子控制器之间都是NaviController管理的,A,B,C子控制器被弹出来的时候,是ViewCotrollers数组对A,B,C进行强引用。而不是B弹出CB强引用C。所以这一波控制器之间的传递Block其实是没有循环引用的,但是自定义View和控制器之间就很可能循环引用。所以看到self.就思考下是否循环引用。

以上是关于Block控制器传值和内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

block块中引用成员变量引起内存泄漏问题

来自 Foundation 和 CFNetwork 库的内存泄漏

APP出现内存泄漏的几种情况

内存泄漏

iOS 内存泄漏导致更改视图控制器崩溃

VS2005 检测内存泄漏的方法(转载)