美文网首页
2019-04-24 _NSInlineData 和 Dispa

2019-04-24 _NSInlineData 和 Dispa

作者: 小波崽 | 来源:发表于2019-04-24 14:03 被阅读0次

业务背景

近段时间,公司项目要求用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时,解决问题的思路以及
心路历程.若有缘人看到,不喜勿喷.因为我就是个弟弟.如果能帮助到你,那是我的荣幸. 噶油.

相关文章

网友评论

      本文标题:2019-04-24 _NSInlineData 和 Dispa

      本文链接:https://www.haomeiwen.com/subject/plgwgqtx.html