草庐IT

ios - 用 NSURLSession 替换 NSURLConnection

coder 2023-07-29 原文

我一直在着手为 NetworkCommunication 设计。我有一个设计,其中 NSOperation 子类创建和管理它们自己的 NSURLConnectionNSOperation 子类由 NetworkManger 类实例化,该类将其添加到 NSOperationQueue。请求完成后,委托(delegate)(例如:ViewController 将被调用)。这是流程:

网络管理器实例化 NSOperation 子类(封装 URL、参数等)并将其添加到它维护的 NSOperationQueue 中。 NSOperation 子类实例化 NSURLConnection(执行异步请求并检索数据) NSURLConnection 将数据转储到 NSOperation 子类 NSOperation 子类执行委托(delegate)( View Controller )提供的完成 block 。 我正在尝试使用 NSURLSession 实现相同的模式。我希望能够将发出网络请求所需的 url 和参数封装在单个对象中。

如果我使用 NSURLSession,是否可以使用相同的模式?我检查了 AFNetworking 类。但是,他们没有为 NSURLSession 子类化 NSOperation。而且,此外, session 对象应该放在哪里。它会成为 NSOperation 类的一部分吗?

有人可以就此提供一些专家建议吗?我应该能够取消请求、上传(POST/PUT)、下载数据。 Network Manager 类将是任何网络请求的单一联系点。

最佳答案

更新:

NSURLConnection 在 Mac OS 10.11 和 iOS 9 中已弃用。因此,此时应使用 NSURLSession 代替 NSURLConnection。正如 NSURLConnection.h header 所说:

Deprecated: The NSURLConnection class should no longer be used. NSURLSession is the replacement for NSURLConnection.

我的原始答案如下。


答案取决于您是否需要丰富的各种 NSURLSession 委托(delegate)方法。如果您可以使用完成 block 再现(即没有进度回调、没有流等),从 NSURLConnectionNSURLSession 的转换是非常简单的。只需将 NSURLSession 实例放入 NetworkManager 类中,然后将基于委托(delegate)的 NSURLSessionTask 实例包装在并发 NSOperation 中子类,你就完成了。只需采用标准的异步/并发 NSOperation 子类模式即可。

如果您使用的是 NSURLSession 的基于委托(delegate)的再现,则完全不同。主要的麻烦是各种 NSURLSessionTask 委托(delegate)方法是在 session delegate 而不是任务委托(delegate)对象上调用的。乍一看,这可能听起来像是一个微不足道的问题,但是如果您的操作实例具有独特的完成/进度 block ,例如,您会遇到如何让 session 对象将这些委托(delegate)方法回调映射到个人的麻烦原始请求操作实例。

要解决这个问题,您必须维护一个任务标识符到您的 NSOperation 子类对象的映射。然后,您可以在相应的 NSOperation 子类中实现这些 NSURLSessionTask(包括任务、下载任务和上传任务)委托(delegate)方法。然后,NSURLSession 网络管理器类可以在接收到 NSURLSessionTask 委托(delegate)调用时,使用任务标识符来识别适当的 NSOperation 实例,然后在那里调用适当的委托(delegate)方法。

最后,如果您打算处理后台 NSURLSession 实例,生活会变得更加困难(因为即使您的应用程序已终止并且其所有对象都已被丢弃,后台任务仍将继续)。后台 session 根本不适合基于 NSOperation 的方法。

底线,如果您只需要完成 block NSURLSession 方法,这是微不足道的,但如果您需要基于委托(delegate)的再现,这会有点麻烦。

关于ios - 用 NSURLSession 替换 NSURLConnection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24114093/

有关ios - 用 NSURLSession 替换 NSURLConnection的更多相关文章

  1. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  2. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  3. 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返回它复制的字节数,但是当我还没有下

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

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

  5. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  6. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  7. ruby-on-rails - 在这种情况下我如何模拟一个对象?没有明显的方法可以用模拟替换对象 - 2

    假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl

  8. ruby - 如何搜索、递增和替换 Ruby 字符串中的整数子字符串? - 2

    我有很多这样的文档:foo_1foo_2foo_3bar_1foo_4...我想通过获取foo_[X]的所有实例并将它们中的每一个替换为foo_[X+1]来转换它们。在这个例子中:foo_2foo_3foo_4bar_1foo_5...我可以用gsub和一个block来做到这一点吗?如果不是,最干净的方法是什么?我真的在寻找一个优雅的解决方案,因为我总是可以暴力破解它,但我觉得有一些正则表达式技巧值得学习。 最佳答案 我(完全)不懂Ruby,但类似这样的东西应该可以工作:"foo_1foo_2".gsub(/(foo_)(\d+)/

  9. ruby - 改变替换的大小写 - 2

    我有以下内容:text.gsub(/(lower)(upper)/,'\1\2')我可以将\2替换为大写吗?类似于:sed-e's/\(abc\)/\U\1/'这在Ruby中可行吗? 最佳答案 查看gsub文档:str.gsub(模式){|匹配|block}→new_str在block形式中,当前匹配字符串作为参数传入,$1、$2、$`、$&、$'等变量将被适当设置。block返回的值将替换为每次调用的匹配项。"alowerupperb".gsub(/(lower)(upper)/){|s|$1+""+$2.upcase}

  10. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

随机推荐