V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Taoist
V2EX  ›  iOS

AI 辅助编程实战:从零到一开发 Swift 性能框架的经验分享

  •  
  •   Taoist · 1 天前 · 669 次点击

    [实验] 此文章由 Cursor 根据项目翻阅项目代码和文档后, 加上本人的一些信息输入自动生成, 我只改了几处明显的错误, 每处不超过一行

    前言

    作为一名 iOS 开发者,我一直被两个问题困扰:重复的网络请求浪费资源,缓存策略难以精确控制。最近两个月,我决定用 AI 辅助编程的方式来彻底解决这些问题,最终开发出了一个名为Monstra的 Swift 性能框架。

    整个过程让我重新思考了"编程"这个概念,也让我对 AI 协作开发有了全新的认识。今天想分享一下这次 AI 辅助开发的完整经历,包括遇到的坑、解决方案,以及一些意外的收获。

    项目背景:那些让人头疼的性能问题

    问题一:重复网络请求的噩梦

    相信很多 iOS 开发者都遇到过这种情况:

    // 场景:多个 ViewController 同时需要用户数据
    class UserProfileViewController {
        func viewDidLoad() {
            API.fetchUserProfile { result in
                // 处理结果
            }
        }
    }
    
    class SettingsViewController {
        func viewDidLoad() {
            API.fetchUserProfile { result in  // 重复请求!
                // 处理结果
            }
        }
    }
    
    class NotificationViewController {
        func viewDidLoad() {
            API.fetchUserProfile { result in  // 又一个重复请求!
                // 处理结果
            }
        }
    }
    

    结果:3 个页面同时加载,发出 3 个完全相同的网络请求。浪费流量,增加服务器负担,用户体验还差。

    问题二:缓存策略的复杂性

    iOS 开发中的缓存问题同样让人头疼:

    • NSCache: 功能简单,无法精确控制过期时间
    • 自己实现: 要考虑内存限制、过期策略、线程安全等一堆问题
    • 第三方库: 要么功能不全,要么太重太复杂

    决定:用 AI 协作解决这些问题

    面对这些痛点,我决定开发一个专门的框架来彻底解决这些问题。但这次,我想尝试一种全新的开发模式:AI 辅助编程。

    AI 协作开发的分工策略

    经过思考,我制定了一个明确的分工策略:

    我负责的部分(核心创造)

    • 架构设计:整体框架结构,模块划分
    • 核心算法:执行合并逻辑,缓存淘汰策略
    • 业务逻辑:具体的 API 设计和实现
    • 示例代码:真实场景的使用案例

    AI 负责的部分(辅助优化)

    • 单元测试:各种边界情况和异常场景
    • 代码审查:代码质量,最佳实践建议
    • 文档编写:API 文档,README ,使用指南
    • 工程配置:CI/CD ,GitHub Actions ,项目配置
    • 代码规范:注释补全,格式化,命名优化

    这样分工的好处是:我专注于最需要创造性思维的部分,AI 帮我处理那些重复性、规范性的工作。

    框架设计:两大核心组件

    基于对问题的分析,我设计了两个核心组件:

    1. TaskManager:智能任务执行管理器

    MonoTask - 单任务执行合并

    // 创建一个处理用户资料获取的任务
    let userProfileTask = MonoTask<UserProfile>(
        resultExpireDuration: 300.0  // 5 分钟缓存
    ) { callback in
        // 实际的网络请求逻辑
        API.fetchUserProfile { result in
            callback(result)
        }
    }
    
    // 多个地方同时调用,只会执行一次网络请求
    Task {
        let profile1 = await userProfileTask.asyncExecute()  // 发起网络请求
        let profile2 = await userProfileTask.asyncExecute()  // 返回缓存结果
        let profile3 = await userProfileTask.asyncExecute()  // 返回缓存结果
    }
    

    KVLightTasksManager - 轻量级批处理

    // 批量获取用户帖子,自动合并重复 ID
    let postManager = KVLightTasksManager<String, Post>(
        config: .init(
            dataProvider: .asyncMultiprovide(maximumBatchCount: 10) { postIDs in
                return try await API.fetchPosts(ids: postIDs)
            }
        )
    )
    
    // 三个 ViewModel 请求重叠的帖子 ID ,自动批处理
    postManager.fetch(keys: ["101", "102", "103"]) { id, result in
        // 处理单个帖子结果
    }
    

    KVHeavyTasksManager - 重型任务管理

    // 大文件下载,支持进度跟踪和取消
    let downloadManager = KVHeavyTasksManager<URL, Data, Progress, CustomProvider>(
        config: .init(
            maxNumberOfRunningTasks: 2,  // 最多同时 2 个下载
            maxNumberOfQueueingTasks: 64
        )
    )
    
    // 多个下载请求,自动队列管理
    downloadManager.fetch(
        key: fileURL,
        customEventObserver: { progress in
            print("下载进度: \(progress.fractionCompleted)")
        },
        result: { result in
            // 处理下载结果
        }
    )
    

    2. MemoryCache:智能内存缓存系统

    let cache = MemoryCache<String, UIImage>(
        configuration: .init(
            // 内存限制
            memoryUsageLimitation: .init(capacity: 1000, memory: 500), // 500MB
            
            // TTL 配置
            defaultTTL: 3600.0,              // 正常数据 1 小时过期
            defaultTTLForNullElement: 300.0, // 空值 5 分钟过期
            
            // 雪崩保护:随机化过期时间
            ttlRandomizationRange: 60.0,     // ±60 秒随机
            
            // 内存成本计算
            costProvider: { image in
                guard let cgImage = image.cgImage else { return 0 }
                return cgImage.bytesPerRow * cgImage.height
            }
        )
    )
    
    // 优先级缓存
    cache.set(element: profileImage, for: "user-123", priority: 10.0) // 高优先级
    cache.set(element: thumbnail, for: "thumb-456", priority: 1.0)    // 低优先级
    cache.set(element: nil, for: "missing-789")                       // 缓存"未找到"
    
    // 智能获取
    switch cache.getElement(for: "user-123") {
    case .hitNonNullElement(let image): // 找到有效图片
        displayImage(image)
    case .hitNullElement:               // 找到"未找到"记录
        showPlaceholder()
    case .miss:                         // 缓存未命中
        loadImageFromNetwork()
    case .invalidKey:                   // 键值验证失败
        handleInvalidKey()
    }
    

    AI 辅助开发的实战经验

    1. Cursor 的惊人表现

    使用 Cursor 进行 AI 辅助开发最大的感受是:AI 比我想象的更"理解"代码

    代码审查能力

    当我写完核心逻辑后,Cursor 会提出改进建议:

    我的原始代码:

    func removeExpiredElements() {
        for key in keys {
            if isExpired(key) {
                remove(key)
            }
        }
    }
    

    Cursor 的优化建议:

    func removeExpiredElements() -> Int {
        let keysToRemove = keys.filter { isExpired($0) }
        keysToRemove.forEach { remove($0) }
        return keysToRemove.count  // 返回清理数量,便于监控
    }
    

    这种优化不仅提高了性能,还增加了实用功能,完全是我没想到的角度。

    单元测试的全面性

    最让我惊讶的是 AI 生成的单元测试。我只写了基本的功能测试,但 AI 补充的测试用例覆盖了很多我忽略的边界情况:

    // AI 生成的边界测试
    func testConcurrentAccessWithSameKey() {
        // 测试多线程同时访问同一个 key
    }
    
    func testMemoryPressureEviction() {
        // 测试内存压力下的驱逐策略
    }
    
    func testTTLRandomizationPreventsStampede() {
        // 测试 TTL 随机化防止缓存雪崩
    }
    
    func testNullValueCaching() {
        // 测试空值缓存的各种场景
    }
    

    2. 不同 AI 模型的"个性"差异

    在开发过程中,我尝试了多个 AI 模型,发现它们确实有不同的"专长":

    GPT-4 的特点:

    • 保守但严谨:总是考虑各种异常情况
    • 注重边界处理:生成的代码防御性很强
    • 文档详细:API 文档写得非常全面

    Claude 的特点:

    • 性能敏感:经常提出性能优化建议
    • 代码优雅:生成的代码结构清晰,可读性强
    • 注重实用性:更关注实际使用场景

    Cursor 的特点:

    • 上下文理解强:能很好理解整个项目的结构
    • 实践导向:生成的代码更贴近实际开发需求
    • 工程化思维:关注 CI/CD 、项目配置等工程问题

    3. AI 协作的最佳实践

    经过两周的深度协作,我总结出几个关键的协作技巧:

    3.1 精确的需求描述

    ❌ 模糊的描述:

    "我写了一个缓存, 帮我 review 一下"

    ✅ 精确的描述:

    "我写了一个线程安全的内存缓存,支持 TTL 过期,优先级 LRU 淘汰策略,能够缓存 nil 值,防止缓存雪崩,并且可以设置内存使用上限, 请帮我 review 一下代码逻辑正确性 public API 的规范性以及合理性"

    3.2 迭代式优化

    不要指望 AI 一次性生成完美代码,而是通过多轮对话逐步优化:

    第 1 轮:实现基本功能
    第 2 轮:添加异常处理
    第 3 轮:优化性能
    第 4 轮:完善文档
    第 5 轮:添加单元测试
    

    3.3 善用 AI 的不同视角

    对于关键代码,我会让不同的 AI 模型都 review 一遍,综合它们的建议:

    • GPT-4 帮我找 bug 和边界情况
    • Claude 帮我优化性能和代码结构
    • Cursor 帮我完善工程配置

    开发成果:5 个实战示例

    为了验证框架的实用性,我开发了 5 个真实场景的示例:

    1. Module Initialization - 模块初始化

    // 应用启动时的配置加载,支持重试和永久缓存
    let configManager = AppConfigurationManager()
    configManager.initializeModule { result in
        switch result {
        case .success:
            print("配置加载成功")
        case .failure(let error):
            print("配置加载失败: \(error)")
        }
    }
    

    2. User Profile Manager - 用户资料管理

    // 单用户资料管理,支持 TTL 刷新和强制更新
    let profileManager = UserProfileManager()
    profileManager.setUser(firstName: "Alice") { result in
        // 设置完成后自动刷新缓存
    }
    

    3. Object Fetch Task - 批量对象获取

    // 三个 ViewModel 同时请求重叠的帖子 ID ,自动批处理
    let repository = PostRepository()
    repository.getPostsBatch(ids: ["101", "102", "103"]) { results in
        // 批量处理结果
    }
    

    4. Large File Download Management - 大文件下载

    // Alamofire + AFNetworking 双 Provider 支持,断点续传
    let downloadManager = AlamofireManager(config: .init())
    let result = await downloadManager.asyncFetch(
        key: fileURL,
        customEventObserver: { progress in
            updateProgressBar(progress.fractionCompleted)
        }
    )
    

    5. Large File Unzip - 大文件解压

    // ZIPFoundation 集成,进度跟踪
    let unzipManager = UnzipManager(config: .init())
    unzipManager.fetch(
        key: zipFileURL,
        customEventObserver: { event in
            switch event {
            case .progress(let percent):
                print("解压进度: \(percent * 100)%")
            }
        }
    )
    

    性能测试结果

    执行合并效果测试

    // 10 个并发请求测试
    let startTime = CFAbsoluteTimeGetCurrent()
    await withTaskGroup(of: Void.self) { group in
        for i in 0..<10 {
            group.addTask {
                let result = await userTask.asyncExecute()
                print("Task \(i) completed: \(result)")
            }
        }
    }
    let duration = CFAbsoluteTimeGetCurrent() - startTime
    print("总耗时: \(duration)s, 网络请求次数: 1")
    

    结果:10 个并发请求,只发出 1 个网络请求,所有回调都收到相同结果。

    缓存性能测试

    // 缓存命中率测试
    let cache = MemoryCache<String, Data>(capacity: 1000)
    
    // 写入 10000 个条目
    for i in 0..<10000 {
        cache.set(element: randomData(), for: "key\(i)")
    }
    
    // 随机访问测试
    var hitCount = 0
    for _ in 0..<1000 {
        let key = "key\(Int.random(in: 0..<10000))"
        if case .hitNonNullElement = cache.getElement(for: key) {
            hitCount += 1
        }
    }
    
    print("缓存命中率: \(Double(hitCount) / 1000.0)")
    

    AI 协作开发的思考与展望

    对程序员职业的影响

    通过这次深度的 AI 协作开发经历,我对程序员这个职业有了新的思考:

    什么不会被 AI 取代:

    1. 架构设计能力:整体思维,权衡取舍
    2. 业务理解能力:理解用户需求,设计合适方案
    3. 创新思维:发现新问题,提出新解决方案
    4. 质量把控:判断代码质量,做技术决策

    什么会被 AI 大幅提升:

    1. 编码效率:重复性代码生成
    2. 测试覆盖率:边界用例发现
    3. 文档质量:规范化文档生成
    4. 代码质量:最佳实践建议

    未来的编程模式

    我认为未来的编程将是**"人机协作"**模式:

    程序员 = 产品经理 + 架构师 + 质量把控者
    AI = 编码助手 + 测试工程师 + 文档工程师
    

    程序员的价值将更多体现在创造性思维判断决策上,而不是纯粹的编码技能。

    对新手程序员的建议

    1. 尽早开始 AI 协作:不要等技术成熟,现在就开始学习
    2. 关注核心能力:专注算法、架构、业务理解等 AI 难以取代的能力
    3. 培养 AI 协作技能:学会如何与 AI 高效沟通,这将成为核心竞争力

    项目开源与社区反馈

    这个项目现在已经在 GitHub 开源:**github.com/yangchenlarkin/Monstra**

    技术特性

    • 零外部依赖:纯 Swift 实现
    • 全平台支持:iOS 13+, macOS 10.15+, tvOS 13+, watchOS 6.0+
    • 现代 Swift:支持 async/await ,Swift 5.5+
    • 完整文档:API 文档 + 5 个实战示例
    • 高测试覆盖率:AI 辅助生成的全面测试用例

    安装使用

    Swift Package Manager:

    dependencies: [
        .package(url: "https://github.com/yangchenlarkin/Monstra.git", from: "0.1.0")
    ]
    

    CocoaPods:

    pod 'Monstra', '~> 0.1.0'
    

    总结

    这次 AI 辅助开发的经历让我深刻体会到:AI 不是要取代程序员,而是要让程序员变得更强大

    通过合理的分工协作,我们可以:

    • 将更多时间专注于创造性工作
    • 提高代码质量和文档水平
    • 加速项目开发进度
    • 学习到新的编程思路和最佳实践

    如果你还没有开始尝试 AI 辅助编程,我强烈建议你现在就开始。这不仅仅是一个工具,更是编程思维的升级。

    相关链接


    关于作者:iOS 开发工程师,专注于移动端性能优化和架构设计。这是我第一次深度尝试 AI 辅助开发,也是第一个开源项目。如果这个项目对你有帮助,欢迎在 GitHub 上给个⭐️,也欢迎提出改进建议!

    如果你有任何问题或想要交流 AI 辅助开发的经验,欢迎在评论区讨论,或者在 GitHub 上提 Issue 。让我们一起探索编程的未来!

    作者批

    上面的内容都是 Cursor 写的(甩锅 ing), 我这里补充几点:

    1. 任务合并和缓存, 在前端(React)框架中比较常见, 我的灵感也是来自于前端
    2. 文中的各个大模型的特点, 我并没有验证真伪, 这部分大家看个乐呵就好了😂. 不过我在写测试用例的过程中, 我确实真对同一个类, 让不同的大模型给我写测试用例, 然后让 Claude 给我整理 case 、去除重复 case 、规范命名和注释等. 然后我在去阅读这些 case, 发现有遗漏的 case 再让 AI 补充.
    3. 第三方库“要么功能不全,要么太重太复杂”, 这个有失偏颇, 我觉得大部分库还是功能不全, 我这个库才是太重太复杂🤦 大家用的时候根据实际项目各取所需即可, 简单和全面在一定程度上本就是需要做取舍的.
    2 条回复    2025-09-09 14:22:39 +08:00
    WngShhng
        1
    WngShhng  
       1 天前
    为什么不直接用单例+内存缓存呢?
    HolidayBomb
        2
    HolidayBomb  
       1 天前 via iPhone
    从问题一,一看就是从 React 转来的吧?😂原生开发的这种场景和解决方式一般都不这样做,当然选择的方式也会有很多,看个人喜好了。
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3103 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 12:08 · PVG 20:08 · LAX 05:08 · JFK 08:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.