升级Xcode10后遇到的一些问题及解决方法
由于要做iPhone XS Max等新设备的适配,所以将Xcode升级到了Xcode10,但是运行工程遇到了一些问题,这里记录下来解决方法。
缺少库:libstdc++.6.0.9.tbd
原因是在Xcode10中默认删除了这个库,如果工程中有依赖于这个库(或其他第三方库引用它)的编译时就会出错。
解决方式是在Xcode9中找到这个库,然后复制到以下路径:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib
如果是模拟器,选择复制到iPhoneSimulator.platform的对应目录下。
编译成功了,但是运行时有报错
dyld: Library not loaded: /usr/lib/libstdc++.6.dylib
Referenced from: /Users/...
Reason: no suitable image found. Did find:
/usr/lib/libstdc++.6.dylib: mach-o, but not built for iOS simulatort
报动态链接库装载出错,看出错提示说是 .dylib 与这个模拟器不符合。这是 Xcode10自带的iOS12模拟器的问题,所以临时的方法也是将这个相关的库从Xcode9.x中copy到Xcode10目录中,切换到iOS11的模拟器运行环境。
将libstdc++.6.dylib
、 libstdc++.6.0.9.dylib
和libstdc++.dylib
从Xcode9.x复制到Xcode10以下目录:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib
再次运行时还是报错,提示找不到:-lstdc++
Xcode10_lstdc++_issue.png遇到这个问题也是挺憋屈的,其实不是什么代码的问题,配置也没什么错误,检查了很多地方,最后在Buildertime中第一项中,点击update工程的.project文件,然后就弹出一个窗口,选择执行更改xcode.proj文件Setting即可。
1)点击update...
Xcode10_updateXcodeproj.png
2)选择perform Changes
Xcode10_performChanges.png
更新:之前没仔细看到底是些什么设置建议,糊里糊涂地就全选然后执行了。
现在看了下,这个问题应该是-lstdc++这个库变标记过时了,苹果建议我们使用libc++
,所以更新.xcodeproj文件设置时有如下的选项:
在
target -> Build Settings -> C++ Standard Library
,然后就会变成Complier Default,就是说使用默认编译器编译。
objc_msgSend方法报错:
Xcode10_msgSend.png将下面的配置改为NO即可。
Xcode10_strict_checking_objc.png
查看message.h的代码:
#if !OBJC_OLD_DISPATCH_PROTOTYPES
OBJC_EXPORT void
objc_msgSend(void /* id self, SEL op, ... */ )
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_msgSendSuper(void /* struct objc_super *super, SEL op, ... */ )
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
#else
OBJC_EXPORT id _Nullable
objc_msgSend(id _Nullable self, SEL _Nonnull op, ...)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
所以如果上面配置成YES的话,就会严格检查objc_msgSend的函数调用,这就不能用第二种方法了。需要设置成NO,才能使用下面的有参数列表的函数调用。(这在以前的版本(9.3.1)中设置为YES也不会提示错误,不知道是不是Xcode10的更新导致)
关于这个函数说明,请参考这篇文章
更新了.xcodeproj文件后,再次编译还报了如下错误:
1050 duplicate symbols for architecture x86_64
/clang:-1: linker command failed with exit code 1 (use -v to see invocation)
这个问题很明显是存在重复的文件或重复定义了某个变量(这个变量是在@interface和@implement外面的)。而代码中确实也存在着在不同文件中声明了同名的变量(没有使用extern
关键字),一般关闭了Xcode中的下面这个属性设置后是不会提示的。但是更新xcode设置时没有仔细看,导致更新打开了属性:
Build Setting中的NO Common Blocks
。官方说明如下:
In C, allocate even uninitialized global variables in the data section of the object file, rather than generating them as common blocks. This has the effect that if the same variable is declared (without extern ) in two different compilations, you will get an error when you link them. The only reason this might be useful is if you wish to verify that the program will work on other systems which always work this way.
意思是说如果开启了这个配置,当你在两个不同的编译环境中声明了相同的变量(没有使用extern关键字)时,在你链接它们的时候就会抛出一个错误。
所以我们需要前往编译设置中将其修改为NO或者使用extern关键字即可。再次编译就不会这个报错了。
Xcode_no_common_setting.jpg
C/C++中的extern关键字的作用是:extern可以
创建外部文件可以访问的全局变量
,这样就可以达到多个类同时操控同一变量的目的。
编译错误:Multiple commands produce '/Users...
编译时出现如下错误:
:-1: Multiple commands produce
'/Users/idev/Library/Developer/Xcode/DerivedData/.../Build/Products/Release-iphoneos/xxx/Info.plist':
1)Target 'xxx' (project 'xxx') has copy command from '/Users/idev/developer/xxx/xxx/Info.plist' to '/Users/idev/Library/Developer/Xcode/DerivedData/...Build/Products/Release-iphoneos/xxx.app/Info.plist'
2)Target 'xxx' (project 'xxx') has process command with output '/Users/idev/Library/Developer/Xcode/DerivedData/.../Build/Products/Release-iphoneos/xxx.app/Info.plist'
解决:
在 target -> Build phase > Copy Bundle Resource
中找到info.plist,移除info.plist文件,然后重新编译即可。