You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Swift字典循环代码,实现逐个询问并等待输入?

修复Swift字典遍历的交互式询问代码

我来帮你搞定这个问题!你想要遍历字典里的每一个成员,逐个询问是否参加,并且等用户输入后再进行下一个,对吧?原来的for循环是同步执行的,没法停下来等用户的异步输入(比如弹窗选择),所以我们需要用异步的方式来控制遍历节奏,下面是几种可行的方案:

方案一:使用Async/Await(推荐,适配iOS 15+、macOS 12+)

这个方法利用Swift的异步等待特性,让遍历过程在每个询问后暂停,等用户做出选择再继续,代码更简洁易读:

import Foundation
import UIKit

class AttendeeManager: UIViewController {
    var squad = [1:"Arsh", 2:"Arbab", 3:"Ayush", 4:"KC", 5:"Jaski", 6:"Gunny", 7:"Harsh", 8:"Nagib", 9:"Rithin", 10:"Gursh", 11:"Sonny"]
    var attendees = [String]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 启动异步遍历任务,不阻塞主线程
        Task {
            await askAttendeesSequentially()
            // 所有询问完成后,输出结果
            print("最终参会名单:\(attendees)")
        }
    }
    
    private func askAttendeesSequentially() async {
        // 先按字典的key排序,保证询问顺序固定(字典默认无序)
        for (_, name) in squad.sorted(by: { $0.key < $1.key }) {
            let isComing = await askUserAboutAttendee(name: name)
            if isComing {
                attendees.append(name)
            }
        }
    }
    
    // 把弹窗的异步回调转换成可等待的异步函数
    private func askUserAboutAttendee(name: String) async -> Bool {
        return await withCheckedContinuation { continuation in
            let alert = UIAlertController(title: "参会确认", message: "\(name) 是否参加?", preferredStyle: .alert)
            
            alert.addAction(UIAlertAction(title: "Yes", style: .default) { _ in
                continuation.resume(returning: true)
            })
            
            alert.addAction(UIAlertAction(title: "No", style: .cancel) { _ in
                continuation.resume(returning: false)
            })
            
            present(alert, animated: true)
        }
    }
}

方案关键点:

  • 用Task包裹异步逻辑,避免阻塞UI主线程
  • withCheckedContinuation将UIAlert的异步回调转换为可await的函数,让循环能暂停等待用户输入
  • 对字典进行排序,确保每次询问的顺序一致(字典本身是无序集合)

方案二:使用Completion Handler(兼容iOS 14及以下)

如果需要适配更早的系统,我们可以用递归的方式,每次处理完一个用户的输入后,再触发下一个成员的询问:

import Foundation
import UIKit

class AttendeeManager: UIViewController {
    var squad = [1:"Arsh", 2:"Arbab", 3:"Ayush", 4:"KC", 5:"Jaski", 6:"Gunny", 7:"Harsh", 8:"Nagib", 9:"Rithin", 10:"Gursh", 11:"Sonny"]
    var attendees = [String]()
    // 保存排序后的成员列表,方便递归遍历
    private var sortedMembers: [String]!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 转换为有序数组,固定询问顺序
        sortedMembers = squad.sorted(by: { $0.key < $1.key }).map { $0.value }
        // 开始第一个成员的询问
        askNextAttendee(at: 0)
    }
    
    private func askNextAttendee(at index: Int) {
        // 所有成员询问完毕,输出结果
        guard index < sortedMembers.count else {
            print("最终参会名单:\(attendees)")
            return
        }
        
        let name = sortedMembers[index]
        let alert = UIAlertController(title: "参会确认", message: "\(name) 是否参加?", preferredStyle: .alert)
        
        alert.addAction(UIAlertAction(title: "Yes", style: .default) { [weak self] _ in
            self?.attendees.append(name)
            // 询问下一个成员
            self?.askNextAttendee(at: index + 1)
        })
        
        alert.addAction(UIAlertAction(title: "No", style: .cancel) { [weak self] _ in
            // 直接询问下一个成员
            self?.askNextAttendee(at: index + 1)
        })
        
        present(alert, animated: true)
    }
}

方案关键点:

  • 递归函数askNextAttendee负责逐个处理成员,每次用户选择后触发下一次调用
  • 使用[weak self]避免循环引用,防止内存泄漏
  • 提前将字典转换为有序数组,保证询问顺序稳定

额外:命令行工具版本(非UIKit场景)

如果是在Swift命令行工具中运行,不需要弹窗,直接通过控制台获取输入的话,代码会更简单——因为readLine()会同步阻塞线程,等待用户输入,循环会自然逐个处理:

import Foundation

var squad = [1:"Arsh", 2:"Arbab", 3:"Ayush", 4:"KC", 5:"Jaski", 6:"Gunny", 7:"Harsh", 8:"Nagib", 9:"Rithin", 10:"Gursh", 11:"Sonny"]
var attendees = [String]()

// 按key排序遍历字典
for (_, name) in squad.sorted(by: { $0.key < $1.key }) {
    print("\(name) 是否参加?(Yes/No)")
    // 同步等待用户输入
    guard let input = readLine()?.trimmingCharacters(in: .whitespacesAndNewlines) else {
        continue
    }
    if input.lowercased() == "yes" {
        attendees.append(name)
    }
}

print("最终参会名单:\(attendees)")

内容的提问来源于stack exchange,提问作者Arshveer Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:45:31