技术CTO-关注编程入门知识,提供编程入门教程

您的位置: 首页 > 移动开发 > ios > 正文

NSMutableData接收完数据后,访问异常,大神指点!

来源: 技术CTO 阅读:

服务端WCF服务返回的数据是一个string.


//接收服务返回的数据NSMutableData receivedData 
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (isRequestSuccess) {
        //NSString *responseResult = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];通过这句可以
          //查看到服务段返回的string信息。
        if(data.length > 0){
            if(receivedData == nil){
                receivedData = [NSMutableData dataWithData:data];
            }
            else {
                [receivedData appendData:data];
            }
        }
    }
}

以上接收没有问题,但是下面访问时候出现一个异常(EXC_BAD_ACCESS),有时候可以走下去但是异常是这样-[__NSMallocBlock__ length]: unrecognized selector sent to instance 0x8c91c70,我判断是格式异常(receivedData接收的数据格式异常)。

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    if (isRequestSuccess) {
        if (receivedData.length==0)//这里报EXC_BAD_ACCESS异常,卡住走不下去
        {
            return;
        }
        //略
      }    


附上接收到的数据:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<VerifyUserResponse xmlns="www.orage.com">
<VerifyUserResult>
{"ID":1,"UserBM":"manager","UserName":"小A","Description":"A员","PassWord":"2323","IsManager":false,"StopTag":false,"DepartID":2,"SearchCode":"JSZC","Sex":false,"SexMan":true,"OfficePhone":"0816-2471190","MobilePhone":"434348","Fax":"343434","Email":"adf@126.com","Address":null,"PostalCode":"2323","Birthday":"0001-01-01T00:00:00","CheckAgentUserID":0,"DefOwhsID":61,"CanInPrice":true,"ISRemoteUser":false,"MacAddress":null,"CheckAgentUserName":null,"CanSave":false,"CanOrderCardName":false,"OverDays":0,"DeptName":"","StopTagString":"","IsDefault":false,"LoginMessage":null,"LoginNum":1,"LoginGuid":"4EC7-9BC1-34E9650CB398","OnlineUsers":[{"UserID":"1","UserBM":"man","UserName":"小A","DepartID":"2","DepartName":""}],"DeptPowerIds":null,"AuthCode":"yx/VwXCABG4qFygrC9PB1TZLhx1tTwIbBFc1USDzdjkXkATJcNzL8YV9LRCg2Ffb9ZDJVd95Px4wtKKkiaApKOyooSlSsGRbRc6mbbsvTCquL0emaUfR9L5jShDGDa2f23OgGW9/dbenr7FQ95l7icrY"}
</VerifyUserResult>
</VerifyUserResponse>
</s:Body>
</s:Envelope>

求解析!!!
另外直接在调试的时候display receivedData .length 显示如下信息
Stop hook #1 added.
没有人吗?大虾们指点一二
receivedData是不是空指针了?
原因很明显,receivedData 为nil 而导致的异常。那就找找为什么会是nil ? 
假设在
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
中 返回的data 没有值,在使用data.length 在判断的时候有可能会因不满足条件而无法进入判断的语句体,也就无法执行这句代码:
receivedData = [NSMutableData dataWithData:data];
来对receivedData 进行实例。也就是receivedData 的值为空nil 
当执行到代理方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
时,在判断 if (receivedData.length==0) 时因receivedData为nil,而导致程序的异常

正确的做法:
在外部定义并预先实例化好receivedData对象 


引用 3 楼 zhanglei5415 的回复:
原因很明显,receivedData 为nil 而导致的异常。那就找找为什么会是nil ? 
假设在
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
中 返回的data 没有值,在使用data.length 在判断的时候有可能会因不满足条件而无法进入判断的语句体,也就无法执行这句代码:
receivedData = [NSMutableData dataWithData:data];
来对receivedData 进行实例。也就是receivedData 的值为空nil 
当执行到代理方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
时,在判断 if (receivedData.length==0) 时因receivedData为nil,而导致程序的异常

正确的做法:
在外部定义并预先实例化好receivedData对象 

调试didReceiveData方法中确实有值,receivedData接受以后的长度1024,这个方法每次都正常,而且断点只进入了一次。
但是一到connectionDidFinishLoading方法,receivedData就不正常了。
在外部定义receivedData是这样的,NSMutableData *receivedData ;
那到底什么时候receivedData这个指针变为空了呢?
难道其实不是同一个线程?
引用 4 楼 wolf_y 的回复:
Quote: 引用 3 楼 zhanglei5415 的回复:

原因很明显,receivedData 为nil 而导致的异常。那就找找为什么会是nil ? 
假设在
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
中 返回的data 没有值,在使用data.length 在判断的时候有可能会因不满足条件而无法进入判断的语句体,也就无法执行这句代码:
receivedData = [NSMutableData dataWithData:data];
来对receivedData 进行实例。也就是receivedData 的值为空nil 
当执行到代理方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
时,在判断 if (receivedData.length==0) 时因receivedData为nil,而导致程序的异常

正确的做法:
在外部定义并预先实例化好receivedData对象 

调试didReceiveData方法中确实有值,receivedData接受以后的长度1024,这个方法每次都正常,而且断点只进入了一次。
但是一到connectionDidFinishLoading方法,receivedData就不正常了。
在外部定义receivedData是这样的,NSMutableData *receivedData ;
那到底什么时候receivedData这个指针变为空了呢?
难道其实不是同一个线程?

难道receivedData被提前释放了? 使用
[NSMutableData dataWithData:data]; 静态方法创建实例,它应该是一个autorelease 的对象,说不好在某一时刻被清理。所以你可以尝试将receivedData声明为属性,来帮助你来管理内存。
求大神们继续帮忙分析一下!
引用 5 楼 zhanglei5415 的回复:
Quote: 引用 4 楼 wolf_y 的回复:

Quote: 引用 3 楼 zhanglei5415 的回复:

原因很明显,receivedData 为nil 而导致的异常。那就找找为什么会是nil ? 
假设在
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
中 返回的data 没有值,在使用data.length 在判断的时候有可能会因不满足条件而无法进入判断的语句体,也就无法执行这句代码:
receivedData = [NSMutableData dataWithData:data];
来对receivedData 进行实例。也就是receivedData 的值为空nil 
当执行到代理方法
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
时,在判断 if (receivedData.length==0) 时因receivedData为nil,而导致程序的异常

正确的做法:
在外部定义并预先实例化好receivedData对象 

调试didReceiveData方法中确实有值,receivedData接受以后的长度1024,这个方法每次都正常,而且断点只进入了一次。
但是一到connectionDidFinishLoading方法,receivedData就不正常了。
在外部定义receivedData是这样的,NSMutableData *receivedData ;
那到底什么时候receivedData这个指针变为空了呢?
难道其实不是同一个线程?

难道receivedData被提前释放了? 使用
[NSMutableData dataWithData:data]; 静态方法创建实例,它应该是一个autorelease 的对象,说不好在某一时刻被清理。所以你可以尝试将receivedData声明为属性,来帮助你来管理内存。

先谢谢了!终于有写思路了,我对这个文件加了-fno-objc-arc,禁用了arc,
调试发现receivedData这个在connectionDidFinishLoading中是0 object.应该确实是提前被释放了。
为什么禁用了arc,这个还是被提前清理了呢?

上传一张receivedData的图片。

^_^ 如果您热爱技术、热爱编程,想与更多的朋友一起交流学习,欢迎加入本站官方QQ群:345733473 ^_^