理解 plank 自动生成的 copyWithBlock: 方法

当你使用 plank 命令自动生成一个类时

./plank --objc_class_prefix=PUG --no_runtime --no_recursive user.json

分析

在 JSON 目录下, 执行如上命令后, 生成的 PUGUser 对象, 会自带 copyWithBlock: 方法, 这个方法是用来做什么的 ?

copyWithBlock: (注意末尾有一个冒号,因为它需要一个 Block 参数)是 Plank 为 每一个不可变模型类自动生成的“便捷变异”接口。它的核心作用可以概括为:

在保持原对象不可变的前提下做局部修改

Plank 生成的 PUGUser 属性全部是 readonly。想改动其中某个字段时,你不能直接赋值,只能构造一个新实例。
copyWithBlock: 会先用当前对象创建一个 Builder (PUGUserBuilder),把现有属性拷贝过去 → 你在 Block 里改 Builder 的可写属性 → Plank 再把 Builder build 成一个全新的 PUGUser 并返回。
整个过程中旧对象完全不变,线程安全、易于推导状态。(pinterest.github.io)

语法更简洁、可读性更好
与“自己手动 new Builder → 拷贝属性 → 设置新值 → build”相比,它把所有模板代码都藏在方法内部,调用者只需已关注真正要改的字段:

PUGUser *updatedUser =
    [originUser copyWithBlock:^(PUGUserBuilder *builder) {
              
        builder.username = @"new_name";
        builder.bio      = @"喜欢 Objective-C 的人";
    }];

这样一眼就能看出变动点。Plank 官方文档把它称为 fluent interface for mutation —— 一条链式语句即可完成复制 + 变更 + 生成。(pinterest.github.io)

mergeWithModel: 的区别

copyWithBlock::你显式地告诉 Builder 要改什么。
mergeWithModel::把另一个最新对象的“已设置字段”并入当前对象,用于渐进式加载(例如网络增量更新)。内部实现同样依赖 Builder,但合并逻辑由框架自动决定。

常见使用场景

UI 层拿到旧模型,用户修改昵称 / 头像等局部信息,立即生成新模型推送给上层数据流。
在自建数据同步层(例如通过通知分发模型变更)时,用 copyWithBlock: 保证每一次变更都会得到一个全新的、可比较的新对象,方便 diff 与渲染。(GitHub)

总结copyWithBlock: 就是 Plank 给不可变模型提供的“Builder-封装版 copy+局部修改”方法:
输入 = 旧对象 + 你的修改指令;
输出 = 一个只在指定字段上不同的新 PUGUser 实例。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容