美文网首页
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