草庐IT

ios - 在后台执行网络和其他耗时的任务

coder 2024-01-13 原文

我正在开发一个基于网络的 iOS 应用程序,它从服务器下载 json 数据并进行处理。下载任务和处理任务都需要很长时间才能完成,所以我不想在主线程上执行。

我认为有两种方法可以做到这一点:

  1. 使用 NSURLConnection 执行异步加载,并在 didFinishLoading 方法中使用 GCD(比方说)在后台进行处理。

  2. 使用GCD dispatch_async(比方说)在后台开始工作并使用NSURLConnection sendSynchronousRequest:returningResponse:error同步下载数据,对数据进行处理,并在主线程调用UI更新。

我认为第二种方法更容易编写并且会产生更清晰的代码,特别是如果一个“下载/处理数据”任务涉及多个顺序服务调用以下载数据。因此,而不是像这样执行:

ma​​in(启动)-> background(下载)-> main(NSURLConnectionDelegate 方法)-> background(数据处理)-> main(UI 更新)

我们会:

ma​​in(开始)->后台(下载)->后台(数据处理)->main(UI更新) 这对我来说似乎更干净。

我发现了 2 个类似的问题:Good pattern for Internet requests with Grand Central Dispatch? 还有
NSURLConnection and grand central dispatch

这两个问题的答案似乎都建议使用概念上类似于方法 1 的方法。

是否没有合适的方法来实现方法 2 中描述的内容?

提前致谢!

最佳答案

我不会倾向于追求选项 #2。虽然它具有一定的简单性,但 sendSynchronousRequest 不提供下载期间的进度更新、取消请求的能力(以及其他更复杂的场景)。 NSURLConnectionDataDelegate 方法让您可以更好地控制网络请求。

这个问题假定基于 GCD 的模式,但我认为操作队列模式值得考虑。您可以将 NSURLConnectionDataDelegate 方法提供的控件与封装网络请求的可取消操作结合起来。当你开始变得更复杂时,你可以开始使用并发请求,但也要限制并发程度(例如,不超过五个并发请求)。

我建议看一下 AFNetworking .也许您不想使用该框架,但我仍然会看一下它使用的基于操作队列的模式。我个人会使用该模式而不是上述任何一种 GCD 方法。

关于ios - 在后台执行网络和其他耗时的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15263231/

有关ios - 在后台执行网络和其他耗时的任务的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  4. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  5. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  6. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  7. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  8. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  9. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  10. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

随机推荐