1、 什么是Block?
Block是将函数以及其执行上下文封装起来的对象。
2、 Block和函数指针的区别是什么?
Block和函数指针都可以用来引用代码,但主要区别在于Block可以捕获其定义环境中的变量,而函数指针不能。此外,Block是Objective-C的对象,可以加入到NSArray或NSDictionary等集合中,而函数指针是C语言的概念,不能直接存储在Objective-C的集合中。
3.Block一般用什么关键字修饰,为什么?哪些情况会引起Block循环引用,如何解决?
copy关键字修饰,因为创建block是在栈内存里面,需要通过copy放入堆内存进行管理。
一个对象强引用了block,在block中又强引用了该对象,就会形成循环引用;可以在block引用A时使用weak解决。
4、 如何避免Block中的循环引用?
在Block内部使用外部对象时,如果直接引用这些对象,可能会导致循环引用,特别是当Block被对象持有时。为了避免这种情况,可以使用__weak或__block修饰符来声明外部变量。__weak修饰符可以创建一个弱引用,它不会增加对象的引用计数。__block修饰符用于可变变量或在Block内部需要修改的变量。
5、 Block的内存管理是如何工作的?
Block默认是在栈上创建的,当Block作为函数返回值时,它会自动复制到堆上。如果Block被赋值给__strong指针或者被Objective-C容器类持有,同样会被复制到堆上。在堆上的Block需要手动管理内存(在非ARC环境下),或者在ARC环境下自动管理。复制到堆上的Block会捕获其使用的所有外部变量的副本。
6、 举个使用Block的例子。
Block在iOS开发中经常用于处理异步任务的回调。例如,我们可以使用Block来处理网络请求的响应:
[self fetchDataFromServerWithCompletion:^(NSData *data, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
NSLog(@"Data received: %@", data);
}
}];在这个例子中,fetchDataFromServerWithCompletion:方法接受一个Block作为参数,这个Block用于处理网络请求完成后的数据或错误。
这些问题和答案应该能够帮助面试者理解和回答有关Block的面试题。
7.Block的几种形式
- 全局Block :不使用外部变量的Block是全局Block
- 栈Block :使用外部变量且未进行copy操作的Block是栈Block
- 堆Block :对栈Block进行copy操作的的Block是堆Block;而对全局Block操作后仍然是全局Block
