1. Block 的内存管理
objectivec
// Block 的基本结构
struct Block_layout {
void *isa; // Block 的类型信息
volatile int32_t flags; // 标志位,包含引用计数等信息
int32_t reserved; // 保留字段
void (*invoke)(void *, ...); // 函数指针,指向 Block 的实现
struct Block_descriptor *descriptor; // Block 的描述信息
};
// Block 的描述信息
struct Block_descriptor {
unsigned long int reserved; // 保留字段
unsigned long int size; // Block 的大小
// 可选字段
void (*copy)(void *dst, void *src); // 复制辅助函数
void (*dispose)(void *); // 析构辅助函数
};
2. 弱引用处理
objectivec
// 处理 Block 中的弱引用
void Block_object_assign(void *destAddr, const void *object,
const int flags) {
// 根据 flags 判断是强引用还是弱引用
if (flags & BLOCK_FIELD_IS_WEAK) {
// 处理弱引用
weak_register_no_lock(&weak_table, object, destAddr);
}
}
// 清理 Block 中的引用
void Block_object_dispose(const void *object, const int flags) {
if (flags & BLOCK_FIELD_IS_WEAK) {
// 清理弱引用
weak_unregister_no_lock(&weak_table, object, (void *)object);
}
}
3. 引用计数管理
objectivec
// Block 的引用计数管理
bool Block_tryRetain(const void *block) {
struct Block_layout *layout = (struct Block_layout *)block;
// 检查 Block 类型
if (!layout->flags & BLOCK_NEEDS_FREE) {
return true; // 全局或栈上的 Block
}
// 增加引用计数
return OSAtomicIncrement32Barrier(&layout->flags) > 0;
}
void Block_release(const void *block) {
struct Block_layout *layout = (struct Block_layout *)block;
// 减少引用计数
if (OSAtomicDecrement32Barrier(&layout->flags) == 0) {
(*layout->descriptor->dispose)(block);
}
}
4. 内存管理优化
objectivec
// Block 的内存优化
struct Block_byref {
void *isa; // 类型信息
struct Block_byref *forwarding; // 指向自身或堆上的副本
volatile int32_t flags; // 标志位
uint32_t size; // Block 大小
};
// 优化 Block 的复制
static void Block_copy_helper(Block_byref *dst, Block_byref *src) {
// 1. 复制基本信息
dst->forwarding = dst; // 更新 forwarding 指针
dst->size = src->size;
// 2. 处理引用计数
if (src->flags & BLOCK_HAS_COPY_DISPOSE) {
// 调用 copy helper 函数
(*src->byref_keep)(dst, src);
}
}
5. 线程安全处理
objectivec
// Block 的线程安全处理
static void Block_release_internal(void *block) {
struct Block_layout *layout = (struct Block_layout *)block;
// 原子操作处理引用计数
if ((OSAtomicDecrement32Barrier(&layout->flags) & BLOCK_REFCOUNT_MASK) == 0) {
if (layout->flags & BLOCK_NEEDS_FREE) {
_Block_call_dispose_helper(block);
_Block_destructInstance(block);
}
}
}
6. 注意事项
objectivec
/*
Block 使用注意事项:
1. 内存管理:
- 注意循环引用
- 正确使用 __weak 和 __strong
- 注意 Block 的拷贝和释放
2. 线程安全:
- Block 的执行线程
- 数据竞争问题
- 同步访问共享数据
3. 性能考虑:
- Block 的大小
- 拷贝开销
- 内存使用
*/
总结要点:
- 内存管理:
- 引用计数机制
- 弱引用处理
- 拷贝和释放
- 优化机制:
- 内联优化
- 内存布局优化
- 引用计数优化
- 线程安全:
- 原子操作
- 同步机制
- 内存屏障
- 注意事项:
- 循环引用
- 内存泄漏
- 性能影响