动态库下(5)

简介: 动态库下(5)

动态库下(5)


XCFramework


XCFramework: 是苹果官方推荐的, 支持的, 可以更方便的表示一个多个平台和架构的分发二进制库的格式.

需要Xcode11以上支持.

是为更好的支持Mac Catalyst和ARM芯片的macOS.专门在2019年提出的framework的另一种先进格式.


平时开发中会设计到的一些架构


  • iOS/iPad: arm64
  • iOS/iPad Simulator: x86_64 arm64
  • Mac Catalyst: x86_64 arm64
  • Mac: x86_64 arm64


和传统的framework相比


  1. 可以用单个.xcframework文件提供多个平台的分发二进制文件.
  2. 与Fat Header相比, 可以按照平台划分, 可以包含相同架构的不同平台文件.
  3. 在使用时, 不需要再通过脚本去剥离不需要的架构体系.


多架构合并


1. SYTimer -> 编译生成几个不同的需要的架构
2. xcodebuild archive -project 'SYTimer.xcodeproj' \ //指定project-scheme 'SYTimer' \ //指定scheme-configuration Release \ //指定编译的环境-destination 'generic/platform=iOS Simulator' //指定分发的架构平台-archivePath '../archives/SYTimer.framework-iphonesimulator.xcarchive' //指定输出路径SIKP_INSTALL=NO //只有指定为NO的时候才会进行拷贝,方便我们查看最终的编译产物
   1. xcodebuild -> 正常开发过程中使用的构建
   2. archive -> 代表打包
3. 进行真机的架构打包
   1. xcodebuild archive -project 'SYTimer.xcodeproj' 
      -scheme 'SYTimer' 
      -configuration Release 
      -destination 'generic/platform=iOS' 
      -archivePath '../archives/SYTimer.framework-iphoneos.xcarchive' 
      SKIP_INSTALL=NO
   2. SYTimer
4. 通过lipo命令合并
   1. 注意库文件的合并,支持放在一起,进行压缩,并不是真正意义上的合并
   2. lipo命令最大的问题就是相同的架构不能合并. 例如:两个库都有同一种架构
   3. lipo
5. xcFramework
   1. xcframework
6. xcFramework的使用
   1. 直接将生产的xcframework拖拽到 ->  targets/general/frameworks
   2. 引入头文件 #import <SYTimer/SYTimer.h>
   3. XCode编译器,会根据你的程序编译对象,自动选择相应的架构

动静态实战


weak_import


  1. 项目链接SYTimer


// 2. -F: frmaework 所在的目录
FRAMEWORK_SEARCH_PATHS = $(inherited) ${SRCROOT}
// 1. -I :头文件
HEADER_SEARCH_PATHS = $(inherited) ${SRCROOT}/SYTimer.framework/Headers
// 路径
// "/Users/ws/Desktop/VIP课程/第五节、动态库与静态库实战/完成代码/动态库与静态库实战/weak_import/LGApp"
LD_RUNPATH_SEARCH_PATHS = $(inherited)
// 3. 名称
// null -》 runtime -〉 nil
// weak_import
// library
OTHER_LDFLAGS = $(inherited) -Xlinker -weak_framework -Xlinker "SYTimer"


静态库冲突


  1. APP 链接 AFNetworking静态库


//-I
HEADER_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
//-L
LIBRARY_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
//-l
// 冲突
// all_load
// -ObjC
// 两个静态库 -》 库
OTHER_LDFLAGS = $(inherited) -l"AFNetworking" -l"AFNetworking2" -Xlinker -force_load -Xlinker "${SRCROOT}/AFNetworking/libAFNetworking.a"


  1. 编译的时候并没有冲突, 是因为专门为静态库设计的 -noall_load


      1.这时使用all_load,以及-ObjC都不行, 都会将冲突暴露出来

      2.使用-force_load 来只链接其中一个

      3.将其中一个链接生成为动态库.也可以解决


SDK建议:


  1. 一个成熟的SDK,没有理由用了一堆其他的SDK
  2. SDK -> 基本上都是动态库


动动


  1. App -> 使用自己的动态库 -> 自己的动态库使用了其他的动态库.例:AFNetworking
  2. 两种解决方案


      1.脚本copy,参考cocoapods的sh脚本

           1.注意,cocoapods提供动态库的时候,支持提供了链接参数,并没有将动态库copy,只不过最后通过脚本进行了copy


      2.cocoapods, 重新引入其他的动态库到APP

微信图片_20220509215149.png

image.png


  1. 反依赖的情况, 动态库 -> APP


1. 需要APP将需要的头文件暴露出来
   1. Build Phases -> Headers -> project -> 添加需要暴露的头文件 -> 移动到Public
   2. xcconfig -> HEADER_SEARCH_PATH 的头文件暴露
   3. 导入头文件
   4. 编译报错 -> 让APP运行起来,dyld就能找到 -> -undefined
      1. OTHER_LDFLAGS = ... -Xlinker -undefined -Xlinker dynamic_lookup -> 这种写法风险比较大,不建议
      2. OTHER_LDFLAGS = ... -Xlinker -U -Xlinker OBJC_CLASS_LGAppObject为动态库查找的符号
      3. 此时已经反依赖成功.

动静


  1. 关闭cocoapods的user_frameworks! -> 表明引入的是静态库



微信图片_20220509215155.png
image.png


  1. 动态库会将所引用的静态库代码链接
  2. 静态库所有的导出符号相对于动态库来说,还全是导出符号


       1.问题: 给别人提供动态库的时候,不想暴露静态库

       2.

OTHER_LDFLAGS = $(inherited) -ObjC -Xlinker -hidden-l "AFNetworking" -> 可以达到符号的可见性

静静


1. 关闭 use_framerworks -> 表明拉取的是静态库
2. app + 静态库 没问题
   1. 组件静态库 + 组件链接的静态库 -> 有问题,组件链接的静态库相对于APP没有告诉APP链接的三要素
   2. 手动配置三要素,头文件不用了, 需要配置静态库路径,以及静态库名称

静动

1. APP = APP + 静态库 -> 相当于APP直接使用动态库
   1. 静态库 -> 动态库
2. 配置framework路径
3. 进行一个跟上面一样的动动配置.脚本直接使用cocoapods提供的动态库的脚本就可以
    1. APP -> Build Phases -> Run Script -> 执行脚本就可以
    2. 执行脚本的作用就是,进行framework的拷贝

cocoapods即导入静态库又导入动态库


  1. use_frameworks! -> 来控制动静态库
  2. 以下代码达成的效果, 数组里面的都是静态库,不包含的还是默认动态库


target :'LGNetworkManager' do
  use_frameworks!
  # 静态库、动态库
  # 指定需要被编译成static_framework的库
  $static_framework = ['AFNetworking']
  pre_install do |installer|
  installer.pod_targets.each do |pod|
        if $static_framework.include?(pod.name)
            def pod.build_type;
              Pod::Target::BuildType.static_framework
            end
        end
    end
  end
  pod 'SDWebImage'
end


cocoapod 往不同的workspace以及target里面导入动态库的写法


platform :ios, '9.0'
#workspace '../MulitProject.xcworkspace'
target 'LGFramework' do
  use_frameworks!
  pod 'AFNetworking'
end
#target 'LGApp' do
#  project '../LGApp/LGApp.xcodeproj'
#
#  use_frameworks!
#
#  pod 'AFNetworking'
#
#end


总结


  1. XCFramerwork的优点

       1.解决头文件问题

       2.解决调试符号问题

       3.解决相同架构的处理


  1. 实战


1. weak_import: 动态库 运行时不知道这个动态库是否存在 -> 可以使用weak_import来声明一下
2. 静态库冲突 -> APP -> 不存在二级命名空间,并且all_load/-ObjC
3. APP -> 动 动2 -> pod/脚本复制(比较推荐)
   1. reexport重新暴露动2的符号
   2. APP反向依赖
4. APP -> 动 静 -> 静态库不想暴露 -> hidden-l
5. APP -> 静 静2 -> 不知道静2的所在位置
6. APP -> 静 动 ->  编辑就会报错 -> 不知道动态库的位置
   1. 运行时也会报错 ->  动rpath -> pod/脚本复制(比较推荐)


  1. 组件/库 -> 依赖不要太多,最好一个都没有 -> AFN做个封装


实战配置参考


实战配置




目录
相关文章
|
6月前
|
存储 监控 安全
RFID电动车车牌让出行更安全
RFID电动车车牌通过内置芯片实现车辆身份唯一识别,结合物联网技术,提升防盗、交通秩序、事故处理等多方面的出行安全,助力城市电动车智能化管理,守护市民安全出行。
|
12月前
|
运维 Kubernetes Cloud Native
什么是云原生?
云原生(Cloud Native)是一种充分利用云计算弹性和自动化能力的架构理念,核心思想包括以云为中心、模块化与松耦合、自动化运维及弹性容错。其关键技术涵盖容器化(如Docker)、编排调度(如Kubernetes)、微服务和DevOps等。相比传统架构,云原生具备敏捷性、弹性伸缩、高可用性和资源优化等优势,适用于互联网高并发业务、AI/大数据平台及企业转型场景。然而,落地面临技术复杂度高、组织文化转型及安全合规挑战。未来发展趋势包括混合多云管理、智能化运维及WebAssembly等轻量化技术。Gartner预测,到2025年超95%新应用将采用云原生模式开发。
3784 4
|
iOS开发 索引
flutter中好用的Widget-CupertinoPicker
flutter中好用的Widget-CupertinoPicker
915 0
|
机器学习/深度学习 人工智能 搜索推荐
探索人工智能在医疗健康领域的最新进展与未来展望
探索人工智能在医疗健康领域的最新进展与未来展望
770 12
|
缓存 移动开发 JavaScript
WKWebView对网页和js,css,png等资源文件的缓存机制及如何刷新缓存
WKWebView对网页和js,css,png等资源文件的缓存机制及如何刷新缓存
1277 1
|
测试技术 数据安全/隐私保护 iOS开发
iOS自动化测试方案(四):保姆级搭建iOS自动化开发环境
iOS自动化测试方案的第四部分,涵盖了基础环境准备、iPhone虚拟机设置、MacOS虚拟机与iPhone真机的连接,以及扩展问题和代码示例,确保读者能够顺利完成环境搭建并进行iOS自动化测试。
2419 0
iOS自动化测试方案(四):保姆级搭建iOS自动化开发环境
|
人工智能 自然语言处理 数据处理
【AI大模型】Transformers大模型库(十三):Datasets库
【AI大模型】Transformers大模型库(十三):Datasets库
918 0
|
网络协议 网络架构
TCP/IP 协议体系结构四层分别是什么?
TCP/IP协议体系结构四层分别是:1、数据链路层;实现网卡接口的网络驱动程序,以处理数据在物理媒介上的传输。2、网络层;实现数据包的选路和转发。3、传输层;为两台主机上的应用程序提供端到端的通信。4、应用层;负责处理应用程序的逻辑。
|
Swift Perl
OC和swift混合工程更新库时报:target has transitive dependencies that include statically linked binaries
OC和swift混合工程更新库时报:target has transitive dependencies that include statically linked binaries
596 0
|
编解码 调度 UED
Flutter笔记:Flutter的WidgetsBinding.instance的window属性
Flutter笔记:Flutter的WidgetsBinding.instance的window属性
644 0

热门文章

最新文章