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. 注意事项:
  • 循环引用
  • 内存泄漏
  • 性能影响
相关推荐
风别鹤3 小时前
Xcode pod ‘xxx/xxx.h‘ file not found
ide·macos·xcode
承渊政道7 小时前
iOS远程控制电脑用什么好?iPhoneiPad远程控制Windows电脑最佳方案2026横评
windows·ios·远程控制·1024程序员节·iphone ipad
茶底世界之下7 小时前
彩色建筑适合转黑白吗?用 Awaking 检查颜色消失后的层次
ios
猿粪已尽8 小时前
mac 中 iTerm2 使用 rz、sz 上传下载文件详解,附 scp 操作指南
linux·macos·scp·lrzsz
黑科技iOS上架8 小时前
App Store 26年10月新应用审核放缓大量应用不进审
ios·审核
全栈探索者9 小时前
模型去哪下、放哪里、怎么选:Mac 玩 ComfyUI 的模型管理全图景(附我的实盘清单)
人工智能·macos·aigc·stablediffusion·comfyui
OxYGC9 小时前
手机为什么能“自动跳过“开屏广告?李跳跳、GKD 与 iOS 代理软件原理盘点
android·ios·开屏广告·广告屏蔽
snakecy20 小时前
macOS 安装 LaTeX 全流程指南:从 MacTeX 到中文排版
macos·策略模式
终端安全笔记20 小时前
一份配置管十项 AI 功能:它关的是入口,不是数据
网络安全·ios·移动设备管理
2501_915106321 天前
跨平台抓包工具怎么选?TraceEagle抓包鹰 的四种跨平台能力
网络协议·计算机网络·网络安全·ios·adb·https·udp