ASIHTTPRequest 问题总结

1, ASIHttpRequest与30秒超时

今天在项目中发现一个ASIHttpRequest的Bug。这个Bug可能会导致你Http请求延时至少在timeout设置时间结束之后。更可怕的是,为了找出这个Bug,可能会浪费程序员更多的时间。为这个问题我至少奋斗了3个小时!

项目中一直在使用ASIHttpRequest,但有一次,我发现Http请求居然总是不成功。我下意识地以为这是网络延时问题,我延长了ASIHttpRequest的超时时间至30秒,于是程序不再报错。

但今天在使用同样的代码时,我发现以前我全错了。这不是超时的问题,而是ASIHttpRequest的一个Bug。

因为这次我请求本机的Tomcat服务器的某个jsp页面,页面代码写得很简单,在firefox中请求该页面的响应时间不会超过0.01秒,但在iPhone模拟器中居然用了20多秒才返回。这不可能是网络延时的原因。

当我把超时时间改小至10秒,等待超时时间结束,ASIHttpRequest甚至直接报kCFStreamEventErrorOccurred错误。

我打开ASIHttpRequest的所有调试日志,发现ASIHttpRequest似乎在尝试用上次的连接去连接服务器:

Request #3 will use connection #2

Request attempted to use connection #2, but it has been closed -will retry with a new connection

Request #3 will use connection #3

它好像连接时重用上次的http连接。这样肯定是不行的,因为上次的http请求结束后服务器已经把连接关闭了。

于是我们只能把ASIHttpRequest的连接重用关闭:

[requestsetShouldAttemptPersistentConnection:NO];

这样,前面的问题就不会出现了。其实,在不同的http会话中,不应该开启PersistentConnection。

2,iOS使用ASIHTTPRequest请求过来的数据中包含utf-8字符

在使用ASIHTTPRequest请求一个接口时,使用NLog打印出返回的Json串,发现有很少一部分汉字显示的是其UTF-8编码的样式,比如“考试”会显示为“\350\257\225”,其中\350\257\225是“试”utf-8编码,而且没有规律,有些时候这个字显示不正常,有时候显示正常,Android上没有这种问题,在服务端打印出生成的JSON也是正常的,所以接口返回值应该没有问题。服务器返回头的编码是UTF-8,ASIHTTPRequest也设置了UTF8编码:

request.defaultResponseEncoding = NSUTF8StringEncoding;

现在怀疑是 ASIHTTPRequest的问题,不知大家谁遇见过这样的问题,谢谢!

没有错误啊,打印的是那样 但真正显示出来就正常了

3,谨慎使用ASIHttpRequest的block特性

使用ASIHttpRequest的setCompletionBlock、setFailedBlock时碰到一些诡异的内存泄漏和莫名其妙的行为(如:无法release对象)。经过与同事的讨论、查找资料终于得以解决,全是对block理解不透彻惹的祸。

1. 声明ASIHttpRequest时一定要使用__block关键字

  __block关键字告诉block不要retain request,这对于防止循环retain非常重要!!因为request总是会retain block.

2. 谨慎处理block与对象的关系

  当setCompletionBlock/setFailedBlock内部使用对象的instance var时,self会被retain(If you access an instance variable by reference, self is retained;)。所以在request结束前向对象发送release消息不会导致对象的释放(dealloc),亦即:该对象依然可进行所有操作,这将导致诸多你意想不到的结果。

3. 解决第2点的问题

  3.1 仔细拿捏block与对象的关系 + 按值的方式访问instance var(If you access an instance variable by value, the variable is retained.
  3.2 不使用block,而使用ASIHttpRequestDelegate

4. 参考资料

  4.1 http://allseeing-i.com/ASIHTTPRequest/How-to-use - Using blocks
  4.2 Blocks Programming Topics - Object and Block Variables

你可能感兴趣的:(ASIHTTPRequest)