定義
封裝
指的是將對(duì)象的狀態(tài)信息隱藏在對(duì)象內(nèi)部
瓶颠,不允許外部程序直接訪問(wèn)對(duì)象內(nèi)部信息
猩系,而是通過(guò)該類所提供的方法來(lái)實(shí)現(xiàn)對(duì)內(nèi)部信息的操作和訪問(wèn)
昼伴。而SDK封裝
通常是指動(dòng)態(tài)庫(kù)
:.dylib/.
、.framework
.和靜態(tài)庫(kù)
:.framework
食磕、.a
具體來(lái)說(shuō)冗恨,封裝就是把該隱藏的隱藏起來(lái)答憔,把該暴露的暴露出來(lái)
。這兩個(gè)方面通過(guò)OC提供的訪問(wèn)控制符
來(lái)實(shí)現(xiàn)掀抹。
各控制符的作用:
默認(rèn):同一個(gè)包中的類可以訪問(wèn)虐拓。
1:@private(當(dāng)前類訪問(wèn)權(quán)限):只能在當(dāng)前類內(nèi)部被訪問(wèn)。用于徹底隱藏成員變量傲武。在類的實(shí)現(xiàn)部分定義的成員變量相當(dāng)于默認(rèn)用這種訪問(wèn)權(quán)限蓉驹。 (私有的:只有該類可以訪問(wèn)城榛,權(quán)限最小)
2:@package(與映像訪問(wèn)權(quán)限相同):可以在當(dāng)前類以及當(dāng)前類實(shí)現(xiàn)的同一個(gè)映像的任意地方訪問(wèn)态兴。這個(gè)訪問(wèn)控制符用于部分隱藏成員變量狠持。
3:@protected(子類訪問(wèn)權(quán)限):可以在當(dāng)前類、當(dāng)前類的子類的任意部分訪問(wèn)瞻润。用于暴露部分成員變量喘垂。在類的接口部分定義的成員變量默認(rèn)使用這種訪問(wèn)權(quán)限。(受保護(hù)的:該類及其子類的成員可以訪問(wèn)绍撞,同一個(gè)包中的類也可以訪問(wèn))
4:@public(公共訪問(wèn)權(quán)限):可以在任意部分訪問(wèn)正勒,不管是否處于同一個(gè)映像中,不管是否具有父子繼承關(guān)系傻铣。(該類或非該類均可訪問(wèn)章贞,權(quán)限最大)
靜態(tài)庫(kù) VS 動(dòng)態(tài)庫(kù)
靜態(tài)庫(kù)
即是靜態(tài)鏈接庫(kù)
,在編譯時(shí)將代碼拷貝進(jìn)目標(biāo)程序
中非洲,會(huì)導(dǎo)致目標(biāo)程序的體積增加
鸭限。被多次使用就會(huì)在內(nèi)存中存在多份冗余拷貝
。靜態(tài)庫(kù)的代碼就相當(dāng)于是目標(biāo)程序的一部分
動(dòng)態(tài)庫(kù)在編譯時(shí)并不會(huì)被拷貝到目標(biāo)程序中
怪蔑,目標(biāo)程序中只會(huì)存儲(chǔ)指向動(dòng)態(tài)庫(kù)的引用
里覆。等到App啟動(dòng)時(shí)丧荐,動(dòng)態(tài)庫(kù)才會(huì)被真正加載
缆瓣。進(jìn)行rebase指針調(diào)整
和bind符號(hào)綁定
等工作,導(dǎo)致App的啟動(dòng)時(shí)間增長(zhǎng)
虹统。由系統(tǒng)動(dòng)態(tài)加載到內(nèi)存弓坞,供App調(diào)用,系統(tǒng)只加載一次
车荔,多個(gè)程序共用渡冻,節(jié)省內(nèi)存
蘋果的動(dòng)態(tài)庫(kù)發(fā)展史
在iOS 8
之前,iOS平臺(tái)不支持自定義動(dòng)態(tài)庫(kù)忧便,開(kāi)發(fā)者可以使用的動(dòng)態(tài)庫(kù)只能是蘋果自家的 UIKit.framework
族吻、 Foundation.framework
等。這種限制的原因是出于安全考慮
珠增,因?yàn)?code>iOS應(yīng)用都是運(yùn)行在沙盒中超歌,不同的程序之間不能共享代碼,動(dòng)態(tài)下載
代碼是蘋果明令禁止的蒂教,既然沒(méi)辦法發(fā)揮動(dòng)態(tài)庫(kù)的優(yōu)勢(shì)巍举,動(dòng)態(tài)庫(kù)也就沒(méi)有存在的必要了。
在iOS 8
之前凝垛,也有一些第三方提供的.framework文件
存在懊悯,但是它們本質(zhì)上都是靜態(tài)庫(kù)
蜓谋,只不過(guò)通過(guò)一些方法進(jìn)行了包裝,相比較.a文件
使用更方便一些炭分。
iOS 8/Xcode 6
推出后桃焕,iOS平臺(tái)添加了動(dòng)態(tài)庫(kù)的支持,支持開(kāi)發(fā)者有條件地創(chuàng)建和使用動(dòng)態(tài)庫(kù)
捧毛,這種動(dòng)態(tài)庫(kù)叫做 Cocoa Touch Framework
覆旭,但是這種動(dòng)態(tài)framework
與系統(tǒng)的framewor
還是有很大區(qū)別的。系統(tǒng)的framework在編譯時(shí)不需要拷貝進(jìn)目標(biāo)程序中岖妄,而 Cocoa Touch Framework
在打包和提交App時(shí)會(huì)被放到app bundle
中型将,運(yùn)行在沙盒里,不同的app就算使用了相同的framework也是會(huì)有多份的框架被分別簽名荐虐、打包和加載七兜,因此蘋果又把這種framework稱為在Embedded Framework
Cocoa Touch Framework
的推出主要是為了解決兩個(gè)問(wèn)題:從iOS 8開(kāi)始的擴(kuò)展開(kāi)發(fā)
、Swift在早期不支持編譯為靜態(tài)庫(kù)
靜態(tài)庫(kù).framework和.a的區(qū)別
.a是純二進(jìn)制文件 .framework中除了二進(jìn)制文件還有資源文件
.a文件不能直接使用福扬,需要引入.h文件配合 .framework文件包含了.h文件和其他文件腕铸,可以直接使用
.a文件是靜態(tài)庫(kù),.framework 既可以是靜態(tài)庫(kù)也可以是動(dòng)態(tài)庫(kù)
關(guān)于如何制作.a文件
或.framework文件
的教程網(wǎng)上特別多铛碑,這里我就不做具體描述狠裹。這里主要總結(jié)一下幾個(gè)關(guān)鍵點(diǎn)。
架構(gòu)
蘋果的架構(gòu)分為兩大類:
模擬器架構(gòu)
: i386 32位架構(gòu)
汽烦、x86_64 64位架構(gòu)
真機(jī)架構(gòu)
: armv7 32位架構(gòu)
涛菠、armv7s 特殊架構(gòu)
、arm64 64位架構(gòu)
合并架構(gòu)
使用模擬器編譯出來(lái)的包是模擬器架構(gòu)撇吞,使用真機(jī)編譯出來(lái)的包是真機(jī)架構(gòu)俗冻。可以使用lipo -info
查看當(dāng)前包的架構(gòu)類型牍颈。真機(jī)和模擬器架構(gòu)合成的好處是調(diào)試會(huì)非常方便迄薄,缺點(diǎn)是體積會(huì)變大,一般而言煮岁,SDK都需要合成架構(gòu)方便使用者使用讥蔽。合并架構(gòu)的命令:lipo -create simulator.a device.a -output name.a
合并.framework文件的架構(gòu)命令也是使用lipo -create
區(qū)別點(diǎn)是合成的是.framework文件內(nèi)部的可執(zhí)行文件
腳本打包
手動(dòng)打包雖然能滿足我們的需求,但是利用腳本打包會(huì)帶來(lái)幾點(diǎn)優(yōu)勢(shì):
1:提高效率画机,原本繁瑣的打包流程冶伞,只需要執(zhí)行一下腳本就能完成
2:統(tǒng)一規(guī)范,繁瑣的操作流程色罚,依賴個(gè)人去完成碰缔,難免會(huì)出現(xiàn)差錯(cuò),利用腳本可以確保準(zhǔn)確性
3:易于使用戳护,利用腳本打包金抡,即使是新人也可以非常容易的上手瀑焦,降低溝通成本
既然腳本打包有這么多優(yōu)點(diǎn),接下來(lái)就總結(jié)一下實(shí)現(xiàn)腳本打包的過(guò)程:
腳本打包思路
利用xcodebuild
分別打包模擬器架構(gòu)和真機(jī)架構(gòu)
利用lipo -create
合并模擬器和真機(jī)架構(gòu)
如果是framework的合并梗肝,需要將合并了的二進(jìn)制可執(zhí)行文件復(fù)制到framework中
復(fù)制文件到指定目錄下榛瓮,并打開(kāi)文件夾
腳本代碼如下
# 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提供快捷方法
在當(dāng)前項(xiàng)目下新建Aggregate Target
添加Run Script
在Run Script Phases輸入腳本內(nèi)容
編譯Aggregate Target 完成腳本打包