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

Swift调用API时URL(string: url)!处报EXC_BREAKPOINT错误如何解决

崩溃原因

URL(string: url)! 处的崩溃是强制解包nil可选值导致的:URL(string:)构造方法只有传入符合RFC 2396规范的字符串才会返回有效URL实例,当你传入的字符串包含未编码的中文、空格、特殊符号,或者字符串本身为空、格式错误时,该方法会返回nil,用!强制解包nil就会触发EXC_BREAKPOINT运行时崩溃。
另外Postman自动导出的代码使用DispatchSemaphore阻塞线程的写法非常不合理,如果你在主线程调用该方法会直接卡住UI,也建议一并修改。

修复方案

第一步:移除强制解包,增加安全校验

首先修改apiCall方法的URL构造逻辑,避免强制解包:

func apiCall(url: String) {
    let semaphore = DispatchSemaphore(value: 0)
    // 安全校验URL构造结果
    guard let validUrl = URL(string: url) else {
        print("URL构造失败,传入的字符串非法:\(url)")
        semaphore.signal()
        return
    }
    var request = URLRequest(url: validUrl, timeoutInterval: Double.infinity)
    request.httpMethod = "GET"

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        defer {
            semaphore.signal()
        }
        guard let data = data, error == nil else {
            print("请求失败:\(String(describing: error))")
            return
        }
        guard let resultStr = String(data: data, encoding: .utf8) else {
            print("响应数据解析失败")
            return
        }
        print(resultStr)
    }

    task.resume()
    semaphore.wait()
}

如果运行后控制台打印URL构造失败的日志,说明你传入的urlEncode变量本身没有做好编码处理,需要对URL的路径/参数部分提前做百分号编码:

// 示例:对包含特殊字符的字符串做URL编码
if let encodedStr = yourOriginalUrlStr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
    apiCall(url: encodedStr)
}

第二步:优化不合理的信号量写法(推荐)

实际iOS开发中不要用信号量阻塞线程的方式处理异步请求,改成回调式写法更合理,不会卡住线程:

func apiCall(url: String, completion: @escaping (Result<String, Error>) -> Void) {
    guard let validUrl = URL(string: url) else {
        completion(.failure(NSError(domain: "ApiError", code: -1, userInfo: [NSLocalizedDescriptionKey: "URL格式非法"])))
        return
    }
    var request = URLRequest(url: validUrl, timeoutInterval: 30) // 建议设置合理的超时时间,不要用无穷大
    request.httpMethod = "GET"

    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
            return
        }
        guard let data = data, let resultStr = String(data: data, encoding: .utf8) else {
            completion(.failure(NSError(domain: "ApiError", code: -2, userInfo: [NSLocalizedDescriptionKey: "响应解析失败"])))
            return
        }
        completion(.success(resultStr))
    }.resume()
}

// 调用方式
apiCall(url: urlEncode) { result in
    DispatchQueue.main.async { // 涉及UI更新要切回主线程
        switch result {
        case .success(let str):
            print("请求成功:\(str)")
            // 处理业务逻辑
        case .failure(let error):
            print("请求失败:\(error.localizedDescription)")
            // 处理错误
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:24:01