Mac*_*nik 10 objective-c static-libraries objective-c-runtime ios ios-frameworks
以下是其他帖子的引文:
我正在一个iOS项目中工作,该项目包括由另一家公司创建的静态库.该库包含旧版AFNeworking,我没有任何源文件.
现在我需要使用更新的(并且更少的bug)版本的afneworking,但我不能在项目中两次包括相同的类(当然)因为所有"重复的符号"
我的问题是我正在准备一个iOS框架,我想在将来避免这种情况.我不是在谈论AFNetworking,而是其他非常流行的iOS框架.另外,我在原始框架代码中应用了一些自定义更改.
避免"重复符号"和"类X在Y和Z中实现的一种方法.将使用其中一个",我想到的是在原始框架类中添加一些前缀,但是这是正确的解?
更新1:
我试图应用约翰的解决方案,但没有快乐.我创建了一个简化的项目(这里是repo的链接),它有两个类FrameworkClass,它只存在于框架目标中,而SharedClass存在于框架和应用程序目标中,所以也许你可以看看我是否在做某事错误.应用程序启动后,我仍然得到:
objc[96426]: Class SharedClass is implemented in both .../TestFramework.framework/TestFramework and .../SymbolsVisibilityTest.app/SymbolsVisibilityTest. One of the two will be used. Which one is undefined
更新2:
这是我的输出nm基于提供的示例项目的框架输出:
0000000000007e14 t -[FrameworkClass doFramework]
0000000000007e68 t -[SharedClass doShared]
                 U _NSLog
                 U _NSStringFromSelector
00000000000081f0 s _OBJC_CLASS_$_FrameworkClass
                 U _OBJC_CLASS_$_NSObject
0000000000008240 s _OBJC_CLASS_$_SharedClass
00000000000081c8 s _OBJC_METACLASS_$_FrameworkClass
                 U _OBJC_METACLASS_$_NSObject
0000000000008218 s _OBJC_METACLASS_$_SharedClass
0000000000007fb0 s _TestFrameworkVersionNumber
0000000000007f70 s _TestFrameworkVersionString
                 U ___CFConstantStringClassReference
                 U __objc_empty_cache
                 U _objc_release
                 U _objc_retainAutoreleasedReturnValue
                 U dyld_stub_binder`
更新3:
我确实设法通过@bleater 应用解决方案来"隐藏"SharedClass符号,我的输出nm现在是:
         U _NSLog
         U _NSStringFromSelector
00001114 S _OBJC_CLASS_$_FrameworkClass
         U _OBJC_CLASS_$_NSObject
00001100 S _OBJC_METACLASS_$_FrameworkClass
         U _OBJC_METACLASS_$_NSObject
         U ___CFConstantStringClassReference
         U __objc_empty_cache
         U _objc_release
         U _objc_retainAutoreleasedReturnValue
         U dyld_stub_binder`
但我仍然在Xcode中获得双重实施警告.
您应该限制正在开发的任何框架或库中符号的可见性.将默认可见性设置为隐藏,然后将公共接口中的所有函数明确标记为可见.
这可以避免您描述的所有问题.然后,您可以包含任何版本的任何公共库(AFNetworking,SQLite等),而不必担心将来发生冲突,因为链接到您的框架或库的任何内容都无法"看到"这些符号.
要将默认可见性设置为隐藏,您可以进入项目设置并将"默认隐藏的符号"设置为YES.除非您更改它,否则设置为NO.
 
 
至少有几种方法可以将公共界面中的符号标记为"可见".一种是通过使用导出文件,另一种是通过并明确地将某些功能标记为可见:
#define EXPORT __attribute__((visibility("default")))
EXPORT int MyFunction1();
定义显然只是为了方便.您可以定义EXPORT一次,然后只需将EXPORT添加到所有公共符号.
你可以在这里找到官方的苹果文档:
更新:
我看了一下你的示例项目,看起来我指的是错误的方向.您似乎只能真正隐藏C和C++符号.因此,如果您在使用C lib(如sqlite)时出现此问题,则将默认可见性设置为隐藏将起作用.看起来Objective C运行时的本质会阻止您真正使符号不可见.您可以标记这些符号的可见性,但是使用Objective-C,这似乎只是让链接器强制执行您应该或不应该从库中使用的内容(同时仍然使它们可见).
因此,如果您在不同的编译单元中重新定义具有相同名称的Objective-C符号(可能在新版本的流行开源库中进行编译),那么您仍然会发生冲突.
我认为,此时您唯一的解决方案是执行您最初建议的操作,并使用唯一标识符将包含的符号添加到框架中.它不是一个非常优雅的解决方案,但是由于目标C运行时的限制,我相信它可能是最好的解决方案.
| 归档时间: | 
 | 
| 查看次数: | 2085 次 | 
| 最近记录: |