【问题标题】:Download an image from a url, received error “nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed”从 url 下载图像,收到错误“nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed”
【发布时间】:2017-05-03 18:07:17
【问题描述】:

当我从 URL 下载图像时,大约需要 6 秒(即使图像不是高清的)并且在日志中出现错误。

这是我下载图片的代码:

let backgroundQueue = DispatchQueue(label: "my.bk.job", qos: .background, target: nil)
    
backgroundQueue.async {
    let url = URL(string: "https://url/img.jpg")
    let data = try? Data(contentsOf: url!)
    //Show the image
}

这是我得到的日志错误:

2016-12-18 16:16:17.243477 yolo[1111:33384] [] nw_host_stats_add_src recv too small, received 24, expected 28
2016-12-18 16:16:17.247960 yolo[1111:33384] [] __nwlog_err_simulate_crash simulate crash already simulated "nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed: [42] Protocol not available"
2016-12-18 16:16:17.248434 yolo[1111:33384] [] nw_socket_set_common_sockopts setsockopt SO_NOAPNFALLBK failed: [42] Protocol not available, dumping backtrace:
        [x86_64] libnetcore-856.30.16
    0   libsystem_network.dylib             0x000000010c1b7666 __nw_create_backtrace_string + 123
    1   libnetwork.dylib                    0x000000010c495006 nw_socket_add_input_handler + 3164
    2   libnetwork.dylib                    0x000000010c472555 nw_endpoint_flow_attach_protocols + 3768
    3   libnetwork.dylib                    0x000000010c471572 nw_endpoint_flow_setup_socket + 563
    4   libnetwork.dylib                    0x000000010c470298 -[NWConcrete_nw_endpoint_flow startWithHandler:] + 2612
    5   libnetwork.dylib                    0x000000010c48bae1 nw_endpoint_handler_path_change + 1261
    6   libnetwork.dylib                    0x000000010c48b510 nw_endpoint_handler_start + 570
    7   libnetwork.dylib                    0x000000010c4a31f9 nw_endpoint_resolver_start_next_child + 2240
    8   libdispatch.dylib                   0x000000010bf34978 _dispatch_call_block_and_release + 12
    9   libdispatch.dylib                   0x000000010bf5e0cd _dispatch_client_callout + 8
    10  libdispatch.dylib                   0x000000010bf3be17 _dispatch_queue_serial_drain + 236
    11  libdispatch.dylib                   0x000000010bf3cb4b _dispatch_queue_invoke + 1073
    12  libdispatch.dylib                   0x000000010bf3f385 _dispatch_root_queue_drain + 720
    13  libdispatch.dylib                   0x000000010bf3f059 _dispatch_worker_thread3 + 123
    14  libsystem_pthread.dylib             0x000000010c3074de _pthread_wqthread + 1129
    15  libsystem_pthread.dylib             0x000000010c305341 start_wqthread + 13

代码有效,因为我可以看到图像,但速度很慢,而且这个错误对我来说似乎不好,我做错了什么?(我使用的是 Swift 3)

编辑:

我在一个没有任何内容的白色新项目中尝试了该代码,但仍然收到它。

我也复制/粘贴了this 代码,但遇到了同样的错误。

我更改了 URL,现在下载时间是正确的,所以我会保留这个错误,我会使用这个代码。

感谢大家的帮助,我为所有有用的答案投了赞成票

【问题讨论】:

  • 确保在主线程上显示图像
  • 我在viewDidLoad()中显示
  • 显示仍然存在此问题的最小代码(因此尽可能剥离,以免浪费我们的时间)。
  • 好吧,我刚刚尝试了这段代码,它在 swift 3.0 中完美运行,没有任何错误

标签: ios swift


【解决方案1】:

这些无用的日志总是显示在 XCode 8 上。在 XCode 上设置环境变量 OS_ACTIVITY_MODE = Disable Edit Scheme -> Arguments 如果您不想看到它们,请添加。

原则:

1.通过sub threadasync下载任何文件或图像 2.下载后,通过main threadsync更新图片到UI

这很容易解决。

【讨论】:

    【解决方案2】:

    错误/警告可能与您的代码无关。

    请参阅here 了解 SO_NOAPNFALLBK 消息,here 了解其余信息。

    【讨论】:

    • 如果我删除了 backgroundQueue.async(所以图片下载)一切正常,没有任何错误......
    • 除非你在主线程上同步下载,这是个坏主意。这将导致您的 UI 在下载完成时冻结。更糟糕的是,如果下载超时,您的应用可能会因无响应而被终止。
    【解决方案3】:

    你必须在主队列上做 UI 工作:

    backgroundQueue.async {
        let url = URL(string: "https://url/img.jpg")
        let data = try? Data(contentsOf: url!)
        DispatchQueue.main.async {
            //Show the image
        }
    }
    

    【讨论】:

    • 我得到:模块“调度”没有名为“队列”的成员
    • 对不起。更新了答案。
    • 现在我可以运行您的代码,但在日志中出现同样的错误,没有任何变化
    • ShallowThought 的回答是正确的。您绝对必须在主线程上编写 UI 代码。 “//显示图像”行的代码需要包含在对主线程的调用中。 DispatchQueue.main.async() GCD 调用是在 Swift 中执行此操作的常规方法。您也可以使用较旧的 performSelector(onMainThread) 函数,但我不建议这样做。选择器不是很“Swifty”
    猜你喜欢
    • 1970-01-01
    • 2020-12-25
    • 2020-06-22
    • 2017-10-28
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多