iOS - block

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 的大小
   - 拷贝开销
   - 内存使用
*/

总结要点:

  1. 内存管理:
  • 引用计数机制
  • 弱引用处理
  • 拷贝和释放
  1. 优化机制:
  • 内联优化
  • 内存布局优化
  • 引用计数优化
  1. 线程安全:
  • 原子操作
  • 同步机制
  • 内存屏障
  1. 注意事项:
  • 循环引用
  • 内存泄漏
  • 性能影响
相关推荐
用户092 小时前
如何避免写垃圾代码:iOS开发篇
ios·swiftui·swift
HarderCoder16 小时前
iOS 知识积累第一弹:从 struct 到 APP 生命周期的全景复盘
ios
goodSleep21 小时前
更新Mac OS Tahoe26用命令恢复 Mac 启动台时不小心禁用了聚焦搜索
macos
叽哥1 天前
Flutter Riverpod上手指南
android·flutter·ios
用户092 天前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift
YungFan2 天前
iOS26适配指南之UIColor
ios·swift
权咚3 天前
阿权的开发经验小集
git·ios·xcode
用户093 天前
TipKit与CloudKit同步完全指南
ios·swift
小溪彼岸3 天前
macOS自带截图命令ScreenCapture
macos
法的空间3 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios