定义
封装
指的是将对象的状态信息隐藏在对象内部
,不允许外部程序直接访问对象内部信息
,而是通过该类所提供的方法来实现对内部信息的操作和访问
。而SDK封装
通常是指动态库
:.dylib/.
、.framework
.和静态库
:.framework
、.a
具体来说,封装就是把该隐藏的隐藏起来,把该暴露的暴露出来
。这两个方面通过OC提供的访问控制符
来实现。
各控制符的作用:
默认:同一个包中的类可以访问。
1:@private(当前类访问权限):只能在当前类内部被访问。用于彻底隐藏成员变量。在类的实现部分定义的成员变量相当于默认用这种访问权限。 (私有的:只有该类可以访问,权限最小)
2:@package(与映像访问权限相同):可以在当前类以及当前类实现的同一个映像的任意地方访问。这个访问控制符用于部分隐藏成员变量。
3:@protected(子类访问权限):可以在当前类、当前类的子类的任意部分访问。用于暴露部分成员变量。在类的接口部分定义的成员变量默认使用这种访问权限。(受保护的:该类及其子类的成员可以访问,同一个包中的类也可以访问)
4:@public(公共访问权限):可以在任意部分访问,不管是否处于同一个映像中,不管是否具有父子继承关系。(该类或非该类均可访问,权限最大)
静态库 VS 动态库
静态库
即是静态链接库
,在编译时将代码拷贝进目标程序
中,会导致目标程序的体积增加
。被多次使用就会在内存中存在多份冗余拷贝
。静态库的代码就相当于是目标程序的一部分
动态库在编译时并不会被拷贝到目标程序中
,目标程序中只会存储指向动态库的引用
。等到App启动时,动态库才会被真正加载
。进行rebase指针调整
和bind符号绑定
等工作,导致App的启动时间增长
。由系统动态加载到内存,供App调用,系统只加载一次
,多个程序共用,节省内存
苹果的动态库发展史
在iOS 8
之前,iOS平台不支持自定义动态库,开发者可以使用的动态库只能是苹果自家的 UIKit.framework
、 Foundation.framework
等。这种限制的原因是出于安全考虑
,因为iOS应用都是运行在沙盒中,不同的程序之间不能共享代码
,动态下载
代码是苹果明令禁止的,既然没办法发挥动态库的优势,动态库也就没有存在的必要了。
在iOS 8
之前,也有一些第三方提供的.framework文件
存在,但是它们本质上都是静态库
,只不过通过一些方法进行了包装,相比较.a文件
使用更方便一些。
iOS 8/Xcode 6
推出后,iOS平台添加了动态库的支持,支持开发者有条件地创建和使用动态库
,这种动态库叫做 Cocoa Touch Framework
,但是这种动态framework
与系统的framewor
还是有很大区别的。系统的framework在编译时不需要拷贝进目标程序中,而 Cocoa Touch Framework
在打包和提交App时会被放到app bundle
中,运行在沙盒里,不同的app就算使用了相同的framework也是会有多份的框架被分别签名、打包和加载,因此苹果又把这种framework称为在Embedded Framework
Cocoa Touch Framework
的推出主要是为了解决两个问题:从iOS 8开始的扩展开发
、Swift在早期不支持编译为静态库
静态库.framework和.a的区别
.a是纯二进制文件 .framework中除了二进制文件还有资源文件
.a文件不能直接使用,需要引入.h文件配合 .framework文件包含了.h文件和其他文件,可以直接使用
.a文件是静态库,.framework 既可以是静态库也可以是动态库
关于如何制作.a文件
或.framework文件
的教程网上特别多,这里我就不做具体描述。这里主要总结一下几个关键点。
架构
苹果的架构分为两大类:
模拟器架构
: i386 32位架构
、x86_64 64位架构
真机架构
: armv7 32位架构
、armv7s 特殊架构
、arm64 64位架构
合并架构
使用模拟器编译出来的包是模拟器架构,使用真机编译出来的包是真机架构。可以使用lipo -info
查看当前包的架构类型。真机和模拟器架构合成的好处是调试会非常方便,缺点是体积会变大,一般而言,SDK都需要合成架构方便使用者使用。合并架构的命令:lipo -create simulator.a device.a -output name.a
合并.framework文件的架构命令也是使用lipo -create
区别点是合成的是.framework文件内部的可执行文件
脚本打包
手动打包虽然能满足我们的需求,但是利用脚本打包会带来几点优势:
1:提高效率,原本繁琐的打包流程,只需要执行一下脚本就能完成
2:统一规范,繁琐的操作流程,依赖个人去完成,难免会出现差错,利用脚本可以确保准确性
3:易于使用,利用脚本打包,即使是新人也可以非常容易的上手,降低沟通成本
既然脚本打包有这么多优点,接下来就总结一下实现脚本打包的过程:
脚本打包思路
利用xcodebuild
分别打包模拟器架构和真机架构
利用lipo -create
合并模拟器和真机架构
如果是framework的合并,需要将合并了的二进制可执行文件复制到framework中
复制文件到指定目录下,并打开文件夹
脚本代码如下
# Sets the target folders and the finalframework product.
# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME
# 例如: FMK_NAME = "MyFramework" 你生成的就是MyFramework.Framework
FMK_NAME="MyTestFramework"
# Install dir will be the final output tothe framework.
# The following line create it in the rootfolder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework
# Working dir will be deleted after theframework creation.
WRK_DIR=build
DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework
SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework
# -configuration ${CONFIGURATION}
# Clean and Building both architectures.
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build
# Cleaning the oldest.
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
# Uses the Lipo Tool to merge both binaryfiles (i386 + armv6/armv7) into one Universal final product.
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}"
rm -r "${WRK_DIR}"
open "${INSTALL_DIR}"
利用Aggregate提供快捷方法
在当前项目下新建Aggregate Target
添加Run Script
在Run Script Phases输入脚本内容
编译Aggregate Target 完成脚本打包