Iva*_*van 8 xcode cocoa-touch frameworks ios
我有2个框架由我创建,使用(两个)我也创建的库.
第一个框架初始化库并完成其所有工作流程.完成第一个框架后,第二个框架必须启动.但是当第二个开始时,在初始化库之后,使用两个框架的应用程序崩溃并出现exc_bad_access错误.
显然,库是正确创建的,但是如果我在第二个框架中对代码行进行注释以初始化库,则工作流将继续(之后崩溃,因为它没有库初始化).
有什么我做错了吗?我应该使用两个单独的库吗?
编辑:
想象一下情况:
框架A有这样的方法:start,stop.虽然它有效但它委托给方法:infoFromA, frameworkAFinished.
框架B有这样的方法:start,stop.虽然它有效但它委托给方法:infoFromB, frameworkBFinished.
两个启动方法都初始化了所提到的静态库(让我们调用它problematicLibrary).
两个框架都提供了一些视图来实现其功能.所以让我们举一个应用程序工作流程的例子.
在app视图viewWillAppear方法中,我使用以下命令启动Framework A.
[FrameworkA start];,这将初始化库并呈现视图.使用此视图(使用my problematicLibrary),一些信息将委派给infoFromA委派方法.在委托完所有信息后,它将委托给frameworkAFinished.
当FrameworkA委托frameworkAFinished我开始下一个框架时:[FrameworkB start].作为另一个框架,它将初始化库并呈现视图.在调试时,完成了库的所有初始化(创建了所需对象的实例并创建了库的新实例),并且当它呈现视图时,它会通过该viewDidLoad方法然后exc_bad_access在problematicLibrary初始化行引发错误(之前已经完成并继续呈现视图!!)而不从视图中进入任何其他方法.
我已经检查了初始化是否运行良好,并且所有变量在null初始化之前都处于值,并且为库对象提供了新的内存地址.
这听起来像是一个符号冲突给我.我很惊讶链接器没有抓住它,但我认为这是因为你在你的框架中使用静态库而不是简单的另一个框架.
一般来说,我警告说"这是个坏主意".您尝试在设计中引入的内容基本上是依赖关系管理.像很多博客文章一样,特别是这个 SO答案建议,你应该避免将框架(和扩展库)打包到框架中.
什么最有可能发生在你的情况是这样的(我承认我在这里猜测了一下):您链接库中拖入框架A.这样,图书馆成为它的固定部分.它的符号在其中,即使您没有在任何头文件等中将它们暴露给应用程序.只要你只使用它,一切都很顺利.然后是框架B,其中库也是固定部分.即使你无法从你的应用程序中看到它,它内部也会出现相同的符号.然而,这与框架A已经加载的符号冲突,因此崩溃(如上所述,这通常会被链接器捕获,但我想你通过预先构建框架并将库打包到"欺骗"它他们).也许其他人可以更详细地解释这一点,但这很快就会成为你如何寻求解决方案的重点.从我如何看待它,它不会这样工作.
所以这里有一个关于如何解决问题的建议:
如果你真的,真的需要拆分这样的(使用相同的依赖在你的应用程序中使用两个框架),我建议从框架取出库(即让他们依赖于它,而不是打包在实际的某文件他们)并正确记录.然后将库添加到您的应用程序项目,就像您添加了框架一样.
如果你想将这种想象力很容易安装到其他应用程序中,我建议你设置一个私有的CocoaPods存储库并将你的框架变成私有pod.然后,您可以轻松地将库(或者更确切地说是"新框架C")定义为框架A和框架B的依赖项.当您pod install在应用程序中时,cocoapods会计算出依赖关系并自动将Framework C添加到项目中.这种情况正是cocoapods(或任何依赖管理器)的设计目标.它自动化并有助于项目设置,因此最终构建(应用程序)不必动态地弄清楚它能够和不能使用的内容.最终结果是一样的.
试图复制"在代码中"很快变得混乱.框架试图找出使用它们的周围应用程序/项目的东西(比如"我的依赖关系某某已经链接过了?如果没有,我可以加载我自己的库版本吗?")会导致很多痛.
好的,在回复您的评论时,我会尝试更详细的方法来进行非cocoapods设置.不过,作为序言,让我说这有点难以做到,因为我还没有准备好的样本项目.由于这是"设置一次,然后长时间忘记它"之一,我不得不承认我对这些事情的回忆有点模糊,所以认为这是一种"粗略的方向".您可能需要配置的内容与我回忆它们的方式不同.因此,特此邀请其他SO用户在此编辑和更正我的答案.:)
首先,我不得不说我不确定你是否需要将你的静态库转换成一个框架,或者不是为了这个,我想你不这样做我会从这里开始(我从未使用过静态库)办法).这意味着您可以保留按原样构建库的项目.第二个想法,你可能必须这样做才能链接到库而不使它成为使用它的框架的一部分.我仍然会在下面的几点中将此代码称为"库",但假设您也可以将其转换为动态框架.
构建框架A和框架B的项目应该改变.我不知道你是如何设置的(作为一个具有各种目标的项目,你是否有一个"开发应用程序"作为测试框架的一部分,等等),但重要的是在构建框架的目标,库应该链接(即在"Link Binary With Libraries"构建阶段),但不能复制(即它不能在"Copy Bundle Ressources"构建阶段).设置用于运行的任何开发/测试目标可能很棘手,具体取决于您到目前为止的操作方式.例如,您可能必须在构建设置中手动编辑库搜索路径才能正确编译框架.
最后,您需要更改最终应用的项目设置.最初属于框架A和B的库现在需要直接从其项目链接,显然,它也需要复制到包中.请注意,将来包含任一框架(A或B或两者)的任何项目都必须这样做,否则它们将无法工作,因为这些框架期望库存在(但不再"随身携带") ).
尽管有这么长的文本墙,但我认为它不应该那么复杂,但你可能仍然想看看cocoapods如何用这样的东西来支持你,也许它将来会有所帮助.链接的文章期望有关如何使用pod并编写一个的基本知识,但网站上的其他指南很好地解释了这一点.我只是这样说,因为最后,当在项目中使用cocoapods添加多个引入依赖关系的库/框架时,它基本上按照我上面描述的方式设置你的项目.它使用一些花哨的shell脚本,确保所有内容都被复制到正确的文件夹等,但总的来说它是如何工作的:pod的podspec告诉cocoapods你的应用程序中包含哪些额外的pod以使其工作(pod期望的依赖性)在那里,但不会"自带").