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

Swift 4.1中删除用户选中文件的函数失效问题排查

排查Swift中UIAlertAction handler传参删除文件失效的问题

我来帮你分析下这个问题的根源,以及对应的解决办法:

核心问题:文件名后缀重复拼接

你的deleteFileSelected函数里,会自动给传入的fileName拼接.txt后缀:

let searchfilePath = NSString(format:"%@/%@.txt", directoryPath, fileName) as String

但如果你的listFilesPresent()函数返回的文件名已经包含了.txt后缀(比如返回的是"test.txt"而不是"test"),那拼接后的路径就会变成"Documents/test.txt.txt"——这样自然找不到目标文件,删除操作也就失效了。

而你单独传参时偶尔有效,大概率是因为你手动传入的是不带后缀的文件名,刚好匹配了函数里的拼接逻辑。

辅助问题:闭包捕获与代码优化

另外还有几个小细节可以优化,避免潜在问题:

  • 你的deleteFileSelected函数声明返回[String]?但实际返回nil,改成Void类型更合理;
  • 用URL而非字符串拼接路径,更安全且符合Swift的现代写法;
  • 闭包中添加[weak self]避免循环引用,同时显式捕获变量避免意外;

完整修复后的代码

1. 根据文件列表返回值调整删除函数

情况1:listFilesPresent()返回带.txt后缀的文件名

去掉函数里多余的后缀拼接:

func deleteFileSelected(fileName: String) {
    guard let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        print("无法获取Documents目录")
        return
    }
    let fileURL = directoryPath.appendingPathComponent(fileName)
    
    if FileManager.default.fileExists(atPath: fileURL.path) {
        do {
            try FileManager.default.removeItem(at: fileURL)
            print("文件已删除:\(fileName)")
        } catch {
            print("删除失败:\(error.localizedDescription)")
        }
    } else {
        print("目标文件不存在:\(fileURL.path)")
    }
}

情况2:listFilesPresent()返回不带后缀的文件名

保留后缀拼接,但用URL方式实现:

func deleteFileSelected(fileName: String) {
    guard let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
        print("无法获取Documents目录")
        return
    }
    let fileURL = directoryPath.appendingPathComponent("\(fileName).txt")
    
    if FileManager.default.fileExists(atPath: fileURL.path) {
        do {
            try FileManager.default.removeItem(at: fileURL)
            print("文件已删除:\(fileName).txt")
        } catch {
            print("删除失败:\(error.localizedDescription)")
        }
    } else {
        print("目标文件不存在:\(fileURL.path)")
    }
}

2. 优化Alert创建逻辑(更健壮)

直接遍历文件列表添加所有删除选项,同时处理无文件的情况:

@IBAction func deleteConfigAction(_ sender: Any) {
    guard let userFilesPresent = listFilesPresent(), !userFilesPresent.isEmpty else {
        // 没有文件时提示用户
        let alert = UIAlertController(title: "提示", message: "当前没有可删除的文件", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .cancel))
        present(alert, animated: true)
        return
    }
    
    let alert = UIAlertController(title: "删除文件", message: "选择要删除的文件", preferredStyle: .alert)
    
    for fileName in userFilesPresent {
        alert.addAction(UIAlertAction(title: fileName, style: .default, handler: { [weak self] _ in
            self?.deleteFileSelected(fileName: fileName)
            print("要删除的文件:\(fileName)")
        }))
    }
    
    alert.addAction(UIAlertAction(title: "关闭", style: .cancel))
    present(alert, animated: true)
}

验证步骤

  1. 先打印userFilesPresent的内容,确认返回的文件名是否带后缀;
  2. 在deleteFileSelected里打印fileURL路径,对比实际文件路径是否一致;
  3. 运行代码,查看控制台打印信息,确认文件是否存在、删除是否成功。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:52:43