最近在打包的时候,遇到一个坑。特此记录一下

起因是发现 Unity 5.4 版本,使用c#写的下载,下载速度无法突破 2M/s,同样的网络,后来横向对比使用原来 Cocos2d 开始的游戏,可以达到 7M/s。海外推广一般是小包(iOS是150M以内,安卓50M以内) + 扩展包,如果下载速度过慢,对市场推广和用户转化都会有影响(下载等待时间变长了)。然后就决定基于 libcurl 写了一个C++的下载模块,以替换现有的 C# 下载模块。

韩国版本在添加了下载模块进行测试时,遇到了崩溃。使用 Release Run 时,在下载补丁那里必崩(编译是正常的),崩溃的地方是在 curl_easy_init 就挂掉了,很神奇。

最初怀疑是库的添加顺序,尝试调整顺序后发现不是。然后使用排除法,删相关的库,发现有一个库看上去有点奇怪,解压出来发现里面引用了 OpenSSL库,而我们的下载模块也用到了这个库。到这里原因就找到了,因为.a静态库与 第三方的 framework 有冲突(我们使用4个.a文件)。解决方案就是使用 .framework动态库,将4个.a整合成一个动态的.framework,然后添加到Xcode里。

问题解决后,在网上搜索了相关的资料。把相关的知识再重新梳理一遍。

库(Library)分为:静态链接库、动态链接库,下面将三大主流平台动态、静态库做一个简单的对比。

平台

静态库

动态库

Windows *.lib *.dll
Linux *.a *.so
Mac OS *.a,*.framework *.dylib,*.tbd,*.framework

你可能会奇怪,为啥 *.framework 既是动态库又是动态库,系统的 framework 是动态库(Real Framework),我们建立的 framework 是静态库(或者称为伪动态库 —— Fake Framework)。

下面是二个链接,使用 Xcode  build 出 iOS 可使用的 Framework

https://github.com/kstenerud/iOS-Universal-Framework

https://github.com/jverkoey/iOS-Framework

iOS 系统的 UIKit.framework 不需要拷贝到目标程序中,我们生成的 Framework 即便是动态的,最后还是需要拷贝到App中,因此苹果又把这种 framework 称为 Embedded Framework。

为什么这么修改就可以了呢?  iOS中的Embedded Framework可以理解为独立的没有main函数的可执行文件。这样就避免冲突了

注:需要注意的是 iOS 8之前是不支持动态库的,只支持静态库。

否则,会报错。

dyld: Library not loaded: @rpath/xx.framework/xx

Referenced from: /var/containers/Bundle/Application/xxx/xx.app/app

Reason: image not found

每次手工将 framework 拖到 xcode肯定是很蛋疼的,增好 Unity 提供了 Xcode API 来解决这个问题。

使用  PBXProjectExtensions 类的 AddFileToEmbedFrameworks 方法

https://docs.unity3d.com/ScriptReference/iOS.Xcode.Extensions.PBXProjectExtensions.html

using UnityEditor.iOS.Xcode.Custom;

string targetName = PBXProject.GetUnityTargetName();
PBXProject proj = new PBXProject();
proj.ReadFromString(File.ReadAllText(projPath));
string target = proj.TargetGuidByName(targetName); string strOSVersion = PlayerSettings.iOS.targetOSVersionString;
string strMajorVersion = strOSVersion.Split('.')[0];
if (int.Parse(strMajorVersion) >= 8)
{
proj.AddFileToBuild(target, proj.AddFile("Frameworks/xx.framework", "Frameworks/xx.framework", PBXSourceTree.Source)); const string defaultLocationInProj = "Frameworks/xx/";
const string coreFrameworkName = "xx.framework"; string framework = Path.Combine(defaultLocationInProj, coreFrameworkName);
string fileGuid = proj.AddFile(framework, "Frameworks/" + framework, PBXSourceTree.Sdk); PBXProjectExtensions.AddFileToEmbedFrameworks(proj, target, fileGuid);
}

更多参考链接:

iOS静态库的链接与加载

iOS动态库、静态库及使用场景、方式

iOS链接库的冲突的更多相关文章

  1. ios 静态库冲突的解决办法

    最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的时候被“坑”了,最后终于顺利的解决了.发现网上也有不少人遇到一样的问题,但是能找到的数量有限的解决办法写得都不详细,很难让人理 ...

  2. iOS 第三方库冲突的处理

    最近项目组在做一些第三方功能的集成,不止一次的遇到第三方库冲突的问题,报错如下: duplicate symbol _OBJC_METACLASS_$_JKSerializer in: /Users/ ...

  3. iOS 静态库,动态库与 Framework 浅析

    静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人 ...

  4. iOS 第三方库、插件、知名博客总结

    iOS 第三方库.插件.知名博客总结 用到的组件 1.通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FMDB 本地数据库组件 SDWebImage 多个缩略图 ...

  5. iOS - 静态库的创建与使用

    在日常项目开发中,不论是为了两个公司项目上的业务交流还是为了减少项目的编译时间,有的时候我们会把项目中的私密内容打包成静态库,或者是把项目中变动较少一部分打包成静态库以便提高编译效率,那么下面我们就来 ...

  6. 【转】iOS动态库和静态库的简要介绍

    静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人 ...

  7. iOS静态库及Framework 创建

    本文转自cocoachina,尊重作者的汗水. 讲述的非常透彻,有需要的朋友可以阅读实践.转载请注明出处 //=================以下留着备份==================// 在 ...

  8. 快快快!27个提升效率的iOS开源库推荐

    文章来源:http://www.csdn.net/article/2015-07-21/2825264-27-ios-open-source-libraries/1 我热爱开源,更喜爱那些花费宝贵的业 ...

  9. MTNET 自用ios网络库开源

    短短两天就在https://git.oschina.net/gangwang/MTNET这里收获15个星 github 5星, 值得收藏! MTNET 自用ios网络库开源, 自用很久了,在数歀上架的 ...

随机推荐

  1. python全栈开发day54-mysql库操作、表操作、数据类型、完整性约束

    一.昨日内容回顾 1.mysql的安装 1).解压文件 添加环境变量bin 2).初始化mysql生成数据data文件夹: mysqld --initialize-insecure 3).mysqld ...

  2. Codeforces 980E The Number Games 贪心 倍增表

    原文链接https://www.cnblogs.com/zhouzhendong/p/9074226.html 题目传送门 - Codeforces 980E 题意 $\rm Codeforces$ ...

  3. Windows 下安装 Ubuntu 双系统(更新)

    Windows + Ubuntu 16.04 ---> 双系统 前言:本篇文章是对之前文章的更新,更新的主内容是把原来用手机拍摄的图片换成了虚拟机的截图,以及对磁盘划分的新的见解和一些使用感受, ...

  4. LeetCode 234. 回文链表

    class Solution { public: bool isPalindrome(ListNode* head) { deque<int> d1, d2; ListNode* p = ...

  5. INSERT 中ON DUPLICATE KEY UPDATE的使用

    如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE.例如,如果列a被定义为UNIQUE,并 ...

  6. POJ 3177 Redundant Paths (边双连通+缩点)

    <题目链接> <转载于 >>>  > 题目大意: 有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新 ...

  7. hadoop离线计算项目上线配置问题记录

    最近上线一个hadoop离线处理项目,因为在低配置(8G,4核)的时候装的CDH,后来集群配置(64G,16核)上来了,但许多参数不会自动修改,需要自己调整,处理过程中遇到的配置问题记录下. 1.hi ...

  8. css3组件之几何图形

    一.平行四边形 1.实心无边框 #parallelogram { width: 150px; height: 100px; -webkit-transform: skew(20deg); -moz-t ...

  9. 响应式网页:用em,rem设置网页字体大小自适应

    「rem」是指根元素(root element,html)的字体大小,好开心的是,从遥远的 IE6 到版本帝 Chrome 他们都约好了,根元素默认的 font-size 都是 16px.这样一个新的 ...

  10. POJ.2175.Evacuation Plan(消圈)

    POJ \(Description\) \(n\)个建筑物,每个建筑物里有\(a_i\)个人:\(m\)个避难所,每个避难所可以容纳\(b_i\)个人. 给出每个建筑物及避难所的坐标,任意两点间的距离 ...