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

Swift函数中如何返回if语句内的值?遇void闭包返回非void值错误

问题分析与解决

错误原因

你碰到的Unexpected non-void return value in void function错误,核心原因有两个:

  1. Timer的尾随闭包是无返回值类型(() -> Void),但你在闭包里写了return copiedString,试图返回String类型的值,和闭包的返回要求不匹配,直接触发报错。
  2. 函数整体逻辑设计错误:Timer是异步执行的,urlclipboardwatcher函数会在创建Timer后立刻执行完毕,根本等不到剪贴板变化的时机,所以就算去掉闭包里的return,这个函数也没法正确返回目标字符串。

修复方案

要获取剪贴板中的目标URL,不能用同步返回值的方式,得改用回调闭包来传递异步结果,修改后的代码如下:

func urlClipboardWatcher(onDetectURL: @escaping (String) -> Void) {
    let pasteboard = NSPasteboard.general
    var changeCount = pasteboard.changeCount
    
    Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak pasteboard] _ in
        guard let pasteboard = pasteboard else { return }
        
        if let copiedString = pasteboard.string(forType: .string), pasteboard.changeCount != changeCount {
            changeCount = pasteboard.changeCount
            
            if copiedString.starts(with: "https://") {
                print(copiedString)
                onDetectURL(copiedString) // 通过回调传递检测到的URL
            }
        }
    }
}

使用方式

调用这个函数时,传入处理URL的回调逻辑,就能在其他模块中使用检测到的URL:

urlClipboardWatcher { detectedURL in
    // 在这里处理目标URL,比如传递给其他模块
    print("获取到URL:\(detectedURL)")
    // 示例:如果是类中的方法,可以把值赋值给属性或者发送通知
    // self.targetURL = detectedURL
    // NotificationCenter.default.post(name: .detectedURL, object: detectedURL)
}

额外说明

  • 代码里的[weak pasteboard]是为了避免循环引用,防止Timer和闭包长期持有对象导致内存泄漏。
  • 如果需要跨模块传递这个URL,除了回调,还可以用NotificationCenter发送通知、单例对象存储,或者结合你项目的状态管理方案(比如ObservableObject、Redux等)来实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:57:24