V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
WildCat
V2EX  ›  iDev

关于 iOS 中 AFNetworking 的封装/设计模式的疑问

  •  2
     
  •   WildCat · 2014-05-01 09:43:13 +08:00 · 11960 次点击
    这是一个创建于 3861 天前的主题,其中的信息可能已经有所发展或是发生改变。
    自己对设计模式不是很了解,目前在V2的iOS客户端把AFNetworking封装成了一个单例对象,但是使用中发现了很多问题:
    1. 很多场景下可能进行多个HTTP请求
    2. V2的服务器在国外,移动端的加载速度不稳定,有可能时间很长,单例模式在这种情况下体验很差

    目前我对AFNetworking封装是这样的:
    由于AFNetworking对于异步请求的回调是基于oc的block,自己感觉在controller里面这样写会很乱,就用了委托模式(delegate),AFNetworking请求的成功和失败都会调用delegate的相关方法,大多数情况下controller为delegate,协议代码如下:
    @protocol V2EXRequestDataDelegate <NSObject>

    @required
    - (void)requestDataSuccess:(id)dataObject;

    @optional
    - (void)requestDataFailure:(NSString *)errorMessage;

    但是这样还是有问题,比如我点了帖子列表第一个帖子的链接,加载了10秒没加载出来,然后想点另外一个,这样会发出两个请求,但是,如果第一个请求最后有了相应,controller会做出错误的判断。
    这个问题怎么解决呢?

    非计算机专业学生,比较菜,望前辈教(tu)导(cao)。
    13 条回复    2014-05-02 10:18:33 +08:00
    PrideChung
        1
    PrideChung  
       2014-05-01 09:48:41 +08:00   ❤️ 1
    参考AFN的demo,把AFHTTPSessionManager弄成单例就行了
    PrideChung
        2
    PrideChung  
       2014-05-01 09:50:36 +08:00   ❤️ 1
    那种把AFN的回调转成Delegate的做法简直是脱裤子放屁,要这么搞你还不如一开始就用NSURLConnection
    wtl
        3
    wtl  
       2014-05-01 10:01:31 +08:00   ❤️ 1
    "比如我点了帖子列表第一个帖子的链接,加载了10秒没加载出来,然后想点另外一个,这样会发出两个请求"
    这个设计有问题,从列表页面点了一个链接,应该跳转到该链接的详情页,然后加载该页面,而不是停留在列表页。
    hoogle
        4
    hoogle  
       2014-05-01 11:02:02 +08:00   ❤️ 1
    @wtl +1
    none
        5
    none  
       2014-05-01 11:04:15 +08:00   ❤️ 1
    正确做法应该是取消前面所有的请求,只执行最后一次请求操作。。。
    WildCat
        6
    WildCat  
    OP
       2014-05-01 14:55:33 +08:00
    @none 似乎没法取消请求。。
    dorentus
        7
    dorentus  
       2014-05-01 15:04:53 +08:00   ❤️ 1
    @WildCat
    可以的啊,请求的时候,应该是有个 AFHTTPRequestOperation 实例的吧,它应该有个名字类似 cancel 的方法,可以取消请求。

    通用的做法是按 wtl 说的那样,点链接是先 push 到详情页,详情页出现时加载内容,消失时取消还没加载完的 operations.
    cielpy
        8
    cielpy  
       2014-05-01 15:09:11 +08:00
    如@wtl 所说,应该是跳转到相应页面然后在viewDidLoad的时候再加载数据吧。
    不知道楼主用的是什么版本的,我看到2.x版本发post请求时, AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager方法会创建一个AFHTTPRequestOperationManager对象,这样的话发第二次请求应该是另一个对象,回调block应该不会有错乱才对。
    cielpy
        9
    cielpy  
       2014-05-01 15:12:41 +08:00   ❤️ 2
    Google了一下,[manager.operationQueue cancelAllOperations];
    可以取消掉所有的请求。
    WildCat
        10
    WildCat  
    OP
       2014-05-01 16:07:12 +08:00 via iPhone
    @dorentus
    @cielpy
    谢谢啦!没有仔细看文档。
    WildCat
        11
    WildCat  
    OP
       2014-05-02 08:52:01 +08:00 via iPhone
    @wtl 关于这个,我认为现在大多数做法还是请求时不切换Controller,因为切换后时一个空白页面要等待好久
    wtl
        12
    wtl  
       2014-05-02 09:21:29 +08:00   ❤️ 1
    @WildCat 大多数程序的行为都是先切换页面再加载 加载的时候可以放个加载动画什么的

    至于网络问题我觉的你不应该多想 这是livid和用户自己的事情 最起码我这里基本是秒开 如果你那儿真是10秒都出不来 我觉的你该和@livid谈谈 看看是哪边的问题
    WildCat
        13
    WildCat  
    OP
       2014-05-02 10:18:33 +08:00
    @wtl 好吧,那我就这么搞了,能简单好多。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3181 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 13:38 · PVG 21:38 · LAX 05:38 · JFK 08:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.