MST

星途 面试题库

面试题:Objective-C中Block语法基础与简单内存管理

请简述Objective-C中Block的基本语法结构,并举例说明如何定义一个简单的Block。同时,阐述在ARC环境下,Block捕获对象时的内存管理机制。
19.2万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

Block基本语法结构

  1. 定义语法返回值类型 (^block名称)(参数列表) = ^返回值类型(参数列表) { 代码块 };
  2. 简化语法:当返回值类型可以从代码块推断出来时,返回值类型部分可以省略。即 (^block名称)(参数列表) = ^(参数列表) { 代码块 };

简单Block定义示例

// 定义一个简单的Block,接收两个int类型参数,返回它们的和
int (^sumBlock)(int, int) = ^(int a, int b) {
    return a + b;
};
// 调用Block
int result = sumBlock(3, 5);
NSLog(@"结果: %d", result);

ARC环境下Block捕获对象时的内存管理机制

  1. 强引用捕获:在ARC环境下,Block默认会对捕获的对象进行强引用。当Block被创建时,会保留(retain)捕获的对象,这确保了在Block执行期间,被捕获的对象不会被释放。例如:
NSObject *obj = [[NSObject alloc] init];
void (^block)(void) = ^{
    NSLog(@"%@", obj);
};
// 此时block对obj有强引用
  1. __weak修饰符:为了避免循环引用(例如,对象A持有一个Block,而Block又捕获了对象A),可以使用__weak修饰符来捕获对象。__weak修饰的变量不会增加对象的引用计数,从而打破循环引用。例如:
__weak typeof(self) weakSelf = self;
self.block = ^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        // 使用strongSelf访问对象属性或方法,这样在block执行期间,对象不会被释放
    }
};
  1. __block修饰符(对于对象):在ARC中,__block修饰符在捕获对象时,对象的内存管理行为与非__block捕获时有所不同。如果用__block修饰对象,Block对该对象的引用是弱引用(但在Block内部使用时,实际操作的是强引用,会自动增加引用计数)。不过,为了避免循环引用,__weak通常是更好的选择,__block更多用于处理基本数据类型和在Block内需要修改外部变量的情况。例如:
__block NSObject *blockObj = [[NSObject alloc] init];
void (^block2)(void) = ^{
    NSLog(@"%@", blockObj);
};
// 这里block2对blockObj的引用相对特殊,实际执行时会涉及更复杂的内存管理操作,但整体是为了在满足需求的同时尽量合理管理内存