最近的工作需要将工程打包成静态库文件,然后提供给别人使用。在工程中有引用第三方类库MBProgressHUD,在打包出静态库文件后,写了个Demo,引用了其中的一段代码来显示MBProgressHUD,在iOS 7模拟器中无错运行。
来到真机测试,在iOS 7的设备上无压力通过。但是在iOS 6的设备上显示MBProgressHUD时却崩溃了,错误提示为:
-[__NSCFString sizeWithAttributes:]: unrecognized selector sent to XXXXXX
由于我的机子上没有iOS 6的模拟器,所以只能借别人的iPhone 4/4S来测试,系统是iOS 6,结果就出现了以上问题。
因此,在这里奉劝大家一定要真机测试(模拟器往往是信不过的),而且一定要多种设备多个版本测试,因为有一些开源类库是不支持低版本的,或者你自己在使用过程中没有注意到版本上的禁忌等。
但是很奇怪的是,我在打包前创建静态库文件的工程中的测试是没问题的。
出现了这样的问题,第一时间谷歌了,结果看到CocoaChina中也有人遇到过这类问题,还问是不是MBProgressHUD自己的Bug,抱着怀疑的态度,我还是从自己的工程出发来思考。
我直接在工程中搜sizeWithAttributes,结果在MBProgressHUD.h中看到了:
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 #define MB_TEXTSIZE(text, font) [text length] > 0 ? [text sizeWithAttributes:@{NSFontAttributeName:font}] : CGSizeZero; #else #define MB_TEXTSIZE(text, font) [text length] > 0 ? [text sizeWithFont:font] : CGSizeZero; #endif
现在问题突然明朗了,因为在iOS 6的设备上调用了iOS 7的API,所以导致了崩溃,也就是上面的“unrecognized selector sent to XXXXXX”。但是,我在Demo中Log出来的__IPHONE_OS_VERSION_MIN_REQUIRED的确是60000,也就是iOS 6,疑惑了。。。
后来想一想,唯一的解释是,静态库文件在打包时,里面的宏的值就固定了下来,也就是上面的MB_TEXTSIZE对应的就是sizeWithAttributes的方法,即iOS 7的API,所以即使Demo工程中的__IPHONE_OS_VERSION_MIN_REQUIRED = 60000也改变不了什么了。
之后问了下老大,果然静态库在编译时里面的宏的值都固定下来了,因此Demo工程中调用的是iOS 7的API,在iOS 6的真机上跑当然崩溃了。瞬间豁然开朗。。。
解决办法:
设置生成静态库工程中的Deployment Target为iOS 6,注意,设置的Target不是工程本身,而是Library自己(有一个小房子的图标):
注意编译出来的API是iOS 6的API,因此iOS 6/7的设备都可以正常跑了,也就解决了上面的问题。
总结:
1.一定要真机测试,而且要多种设备(iPhone 4/4S/5/5S)多种系统版本(iOS 6/7)测试。
2.有时候别人给出来的答案不一定是对的,一定要从自己所处的环境出发思考问题。
MBProgressHUD -[__NSCFString sizeWithAttributes:]: unrecognized selector问题解决,布布扣,bubuko.com