美文网首页
# const之毒

# const之毒

作者: 走着走着就会敲代码了 | 来源:发表于2018-09-27 19:54 被阅读5次

    本文就记录一下最近的一个bug以及解决步骤。这个问题主要是由于const引起,导致第三方库WXOpenIMSDK奔溃。

    背景

    最近在优化项目中的蓝牙打印,原本的蓝牙打印速度实在是不敢恭维哈,按测试的话说:"听着打印声音,等打印等的快睡着了",好吧这个是不能忍,只能优化了不然怎么对得起那几百万的用户量,虽然使用蓝牙打印的用户量只有几十万,蓝牙打印的优化暂时没有时间去整理出文章,这边就先提一下后续会整理。在封装蓝牙打印的类中使用了常量定义一下属性,方便后续调整参数,如下:

    const CGFloat compress      = 0.1f;
    

    而在第三库中也有相同的定义,但是我们是不知道的,是属于未开源的代码中,报错如下:


    报错&线程.png

    打印了下全部的线程,如下:

    (lldb) bt
    **** was compiled with optimization - stepping may behave oddly; variables may not be available.
    * thread #41, stop reason = EXC_BAD_INSTRUCTION (code=1, subcode=0xa0000000)
        frame #0: 0x0000000103e8d3f8 ****`compress
      * frame #1: 0x00000001038bdeb8 ****`::compressData() at TcmPackData.h:106 [opt]
        frame #2: 0x00000001038bdb34 ****`::addSccommHeader() at SccomHelper.cpp:35 [opt]
        frame #3: 0x00000001038c9704 ****`INetImpl::RegisterFd(int, int) [inlined] std::tr1::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<ConnPollFD*, std::tr1::_Sp_deleter<ConnPollFD> >(this=<unavailable>, __p=<unavailable>) at boost_shared_ptr.h:273 [opt]
        frame #4: 0x00000001038c00c0 ****`::syncCall() at TcmInet.cpp:2210 [opt]
        frame #5: 0x00000001038bf638 ****`::exchangeKey() at TcmInet.cpp:298 [opt]
        frame #6: 0x00000001038c0ce8 ****`::LoginToServer() at TcmInet.cpp:983 [opt]
        frame #7: 0x00000001038c307c ****`::loginThreadFunc() [inlined] LoginAuthPw at TcmInet.cpp:1054 [opt]
        frame #8: 0x00000001038c3068 ****`::loginThreadFunc() [inlined] Login at TcmInet.cpp:1120 [opt]
        frame #9: 0x00000001038c3044 ****`::loginThreadFunc() at TcmInet.cpp:1218 [opt]
        frame #10: 0x0000000180b2d75c libsystem_pthread.dylib`_pthread_body + 240
        frame #11: 0x0000000180b2d66c libsystem_pthread.dylib`_pthread_start + 284
        frame #12: 0x0000000180b2ad84 libsystem_pthread.dylib`thread_start + 4
    

    通过以上内容最后是锁定了第三方库WXOpenIMSDK,为了不妨碍其他人员开发只好先把调用第三方库的方法给注释掉,接下来是各种爬坑之旅。
    由于更新了其它一些第三方库(现在挺多第三方库内引用了相同的库容易出问题)以及Xcode 10正式版本发布,去更新了Xcode 也就增加了排查的难度,说多了都是血...

    爬坑——依赖库?

    由于更新了一些库是有可能是由于依赖库的排序问题导致的,毕竟有些是需要让依赖库的先后顺序加载才能正常初始化,只好去拉取旧版本的代码然后一一对比,矫正排序,然后还是崩溃,只能换个方式继续了。

    接着爬——SDK?

    既然不是依赖库的问题,那会不会是第三方库SDK的问题,只好去pod update一波,还是崩溃。�又把Pod更新的库倒回防止增加排查力度...

    再爬——Xcode?

    是不是Xcode的问题啊...毕竟这家伙没少坑人,去更新Xcode,然后发现人更疯了,Xcode 10需要调整以及缺少了一些C++依赖库的问题...当然结果还是徒劳的该崩溃还是接着崩溃。顺带附上Xcode 10调整方法,既然适配好了Xcode 10总不能再倒回去吧,毕竟都是崩溃,只能接着往下爬坑了。

    没辙了——对比文件

    使用Beyond Compare工具,需要的可以自行百度搜索下载哈。文件对比,最好的是两份相近的文件或者源码,但是辣么多小伙伴一直在开发更新Git这个就痛苦了,毕竟检出提交记录需要花一大堆的时间去编译,还有那么多需要对比的提交记录内心是崩溃的,通过半天的时间锁定了最近一段时间内的一些提交记录,又在花了半天的时间锁定了两份相隔就一个提交记录的源码。通过工具Beyond Compare一一对比,就发现一些.m源码的差异,还是没找到问题。最后大胆的猜想是不是Const的问题,尝试着修改常量,发现解决了...心里一万头草泥马狂奔而过。人生本来就这么艰难了,连个const都要来凑热闹下个毒...

    复习Const

    const在一些情况下与宏定义有点类似,但是两者之间还是有区别的。

    宏定义

    宏定义属于预编译指令,在程序运行之前已经编译好了的,并且每一个宏定义都会在内存中临时开辟一份内存空间。

    const

    由于被const修饰,常量是无法被修改的,并且const修饰的常量只被初始化一次,只开辟一块内存空间。

    UIKIT_EXTERN

    一般常量的用法:

    .h
    UIKIT_EXTERN NSString *const kUserName;
    .m
    NSString *const kUserName = @“daver”
    

    在其他类里面可以被调用,类似于宏定义,尽量使用常量定义来代替宏定义,毕竟修改宏定义后需要重新编译(由于项目比较大编译时间太长,尽量能不重新编译就不重新编译),当然在开辟内存上也是有区别的。

    只用于.m中

    由于单纯的在.m中定义会导致其他地方没法调用,但是是存在的,而会出现以上的问题(通过本bug可以推测出的),针对以上问题做了两条建议:

    • 常量名尽量长一些,防止与其他地方冲突
    • 如果是只在某个类内使用,请加上static防止被外部使用,如下:
    static const CGFloat kPrinterCompress      = 0.1f;
    // 或者
    static CGFloat const kPrinterCompress      = 0.1f;
    

    总结

    好吧,总算是解决了,也发个帖子共享下万马崩腾的内心...

    相关文章

      网友评论

          本文标题:# const之毒

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