block和函数指针的理解

来源:互联网 发布:淘宝买家怎么改差评 编辑:程序博客网 时间:2024/06/15 18:18

对于block的理解

1、block跟swift中的闭包(closure)基本一样,都常用于值的回调,特别是在多线程的网络请求回调中,使用起来极为方便。

 

2、block的开头是“^”,接着是由小括号所报起来的参数列,行为主体由大括号包起来。block有四种类型,分别是无参无返回、无参有返回、有参有返回、以及有参无返回,而一般使用的block都是有参block,因为使用block主要就是进行参数的传递。

 

3、使用block时要特别注意类的循环引用,例如在一个控制器中,self强指针指向一个对象,而这个对象又强指针指向一个block,而在block中,又强指针指向了self,从而造成循环引用,导致内存无法释放,造成内存泄露。

 

4、解决循环应用的方法,常用__weak来打断强引用,例如用__weak来定义一个weakself来指向self的地址,如果self被释放,weakself指向的地址变为nil,从而打断引用环。需要注意的是,__weak是ARC专有的,__unsafe__unretained可以用在ARC,也可以用于MRC,但__unsafe__unretained是“assign”形式,如果指向的对象被释放,其指针地址保持不变,如果继续使用该指针,就会出现“野指针”。

 

5、关于block内存管理,当block内部没有引用外部变量时,block存放在全局区;在MRC下,当block内部引用外部变量时,block存放在栈区;当对该栈区的block进行copy操作时,block将存放在堆区。在ARC下,当block内部引用外部变量时,block存放在堆区;关于堆区与栈区的区别,栈区主要存放局部变量,定义的参数等,在函数结束,系统会自动回收其内存空间,而堆区一般用程序员自行分配释放,若程序员不释放,程序结束时,由系统回收。总的来说,使用栈区更为快捷,而使用堆区更为灵活。

 

6、如果要在block中修改外部变量,当变量是static全局变量时,block可以直接修饰,如果不是,可以用__block关键字来修饰,就可以在block内修改变量的值。

 

 

 7.关于block回调理解描述

  举一个��例子:

 比如我很口渴,但我在忙,需要身边的同事打水一起帮忙打,那么我需要把我的水杯给她,让她去将接水(就相当于我们定义了准备了一个代码块,准备接收了外部要传进来的数据),然后她接过水杯就进行去打水,(这个动作相当于:传递者需要准备一个属性用来接收'接收者'准备好的代码块);将水打好交给我(当拿到数据,将数据传递给接收者,实现回调),那么我接到水杯就可以喝水了(就是相当于:拿到传递者的数据,进行我要实现的操作--"赋值");


异同点:

相似点

  1. 函数指针和Block都可以实现回调的操作,声明上也很相似,实现上都可以看成是一个代码片段。
  2. 函数指针类型和Block类型都可以作为变量和函数参数的类型。(typedef定义别名之后,这个别名就是一个类型)

不同点

  1. 函数指针只能指向预先定义好的函数代码块(可以是其他文件里面定义,通过函数参数动态传入的),函数地址是在编译链接时就已经确定好的。
  2. Block本质是Objective-C对象,是NSObject的子类,可以接收消息。
  3. 函数里面只能访问全局变量,而Block代码块不光能访问全局变量,还拥有当前栈内存和堆内存变量的可读性(当然通过__block访问指示符修饰的局部变量还可以在block代码块里面进行修改)。
  4. 从内存的角度看,函数指针只不过是指向代码区的一段可执行代码,而block实际上是程序运行过程中在栈内存动态创建的对象,可以向其发送copy消息将block对象拷贝到堆内存,以延长其生命周期。





原创粉丝点击