业务背景
近段时间,公司项目要求用websocket做一个及时通信,实现人工咨询模块.
要求支持文字.文件.语音聊天,并且支持语音转文字.我就是个弟弟,小小的完
成了任务.实现文件及语音的时候,首先需要将文件(语音,图片都是文件)上传
到服务器,如果是本地的,就直接展示.如果来自服务器,就需要将文件下载到本
地.接下来就是在下载文件到本地,服务器返回的"NSData"并不是你想像中的
NSData.
在上传图片的时候,由于相册中图片的较大,下载完成时,得到的服务器类型
为OSDispatch_Data类型,所以我的想法就是将 OSDispatch_Data转化为
NSData.于是乎,各种找资料.
参考文章
如何将dispatch_data_t转换成NSData
当测试语音消息的时候,发现语音文件不能播放,甚至发生了崩溃.断点调试了
一下,下载完成后,服务器返回的数据类型为 _NSInlineData. 这特么是什么鬼.于
是乎,有开始找干货.
干货
OSDispatch_Data的小探究
OSDispatch_Data这篇文章有点东西的,大佬is大佬,小弟只能膜拜了.里面讲的
非常之清楚.大概的意思就是 _NSInlineData 和 OSDispatch_Data 什么原因造成
的. _NSInlineData 和 OSDispatch_Data 在什么条件下生成的. _NSInlineData文
件较小,OSDispatch_Data文件较大,具体的分界阈值不晓得.最终得到的结论是,这
片文章很吊,但是不能解决 本菜 的问题. 我只想把 _NSInlineData转换成NSData,
但是,get到了不少东西.再次感谢大佬.
怎样把_NSInlineData转换成NSData呢? It's a question!!!!!
然后在网上瞎gb乱搜一顿,并未找到直接的资料.烦 的一批.再找,找到了一篇貌似
有点用的.
iOS-Runtime-Headers
iOS-Runtime-Headers...../_NSInlineData.h
iOS-Runtime-Headers里面有iOS所有的.h文件,包括私有.看一下_NSInlineData.h有
啥?
/* Generated by RuntimeBrowser
Image: /System/Library/Frameworks/Foundation.framework/Foundation
*/
@interface _NSInlineData : NSData {
unsigned short _length;
}
- (id)_createDispatchData;
- (bool)_isCompact;
- (bool)_providesConcreteBacking;
- (const void*)bytes;
- (id)copyWithZone:(struct _NSZone { }*)arg1;
- (id)initWithBytes:(const void*)arg1 length:(unsigned long long)arg2;
- (unsigned long long)length;
@end
接下来看一下之前的dispatch_data_t如何转换成NSData
dispatch_data_t data_t = result;
const void *buffer = NULL;
size_t size = 0;
dispatch_data_t new_data_file = dispatch_data_create_map(data_t, &buffer, &size);
if(new_data_file)
{ /* to avoid warning really - since dispatch_data_create_map demands we
care about the return arg */}
NSData *nsdata = [[NSData alloc] initWithBytes:buffer length:size];
想到拿到_NSInlineData的bytes,length就能想上面那样,转换成NSData.结果不然.一脸懵逼,准备放弃
接着找资料.找了半天,无果.恍惚间,我瞅到了 _createDispatchData 这个方法.难不成可以将 _NSInlineData
转换成dispatch_data_t.果不其然,如我所料.代码最终如下
dispatch_data_t data_t;
if ([result isKindOfClass:NSClassFromString(@"_NSInlineData")]) {
id newResult = [result performSelector:@selector(_createDispatchData)];
data_t = newResult;
}else{
data_t = result;
}
const void *buffer = NULL;
size_t size = 0;
dispatch_data_t new_data_file = dispatch_data_create_map(data_t, &buffer, &size);
if(new_data_file)
{ /* to avoid warning really - since dispatch_data_create_map demands we
care about the return arg */}
NSData *nsdata = [[NSData alloc] initWithBytes:buffer length:size];
总结
以上便是我遇到 服务器返回的"NSData"为_NSInlineData或Dispatch_data_t时,解决问题的思路以及
心路历程.若有缘人看到,不喜勿喷.因为我就是个弟弟.如果能帮助到你,那是我的荣幸. 噶油.
网友评论