iOS - 動(dòng)態(tài)庫(kù)及靜態(tài)庫(kù)的使用

開(kāi)篇

想要構(gòu)建一個(gè)高逼格的應(yīng)用程序,庫(kù)的應(yīng)用必不可少,同時(shí)想要真正進(jìn)入iOS開(kāi)發(fā)的世界”庫(kù)“是我們要掌握的。

那兒_并不遠(yuǎn)

iOS中庫(kù)的相關(guān)概念

  • ** 庫(kù) **:就是一段已經(jīng)編譯好的二進(jìn)制代碼,加上頭文件就可以提供給其他人使用了。iOS中常見(jiàn)的有 .a,.dylib,.Framework等結(jié)尾的庫(kù)。

  • ** 庫(kù)的分類(lèi) **:開(kāi)源庫(kù)和閉源庫(kù)
    **(1)開(kāi)源庫(kù) **:比如我們常用的AFNetworking,源碼都是開(kāi)發(fā)給我們開(kāi)發(fā)者的,下載后copy到項(xiàng)目中可以直接使用。在開(kāi)發(fā)中我們常用的是cocoapods,用命令直接導(dǎo)入開(kāi)源庫(kù),不用關(guān)心開(kāi)源庫(kù)的相關(guān)依賴(lài)。其實(shí)cocoapods的本質(zhì)是將開(kāi)源庫(kù)編譯成靜態(tài)庫(kù),然后使得主工程依賴(lài)此靜態(tài)庫(kù)。
    **(2)閉源庫(kù) **:可以分為靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),像我們開(kāi)發(fā)時(shí)用到的百度地圖等三方框架就會(huì)用到很多閉源庫(kù)。

  • ** 深入理解靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù) **
    **(1)靜態(tài)庫(kù) **:它是你的.m文件編譯而成的二進(jìn)制文件集合,需要配合暴漏在外面的.h文件使用,在程序編譯的時(shí)候會(huì)被直接copy到目標(biāo)程序中,在編譯完成之后,庫(kù)文件實(shí)際就沒(méi)有多大作用了,目標(biāo)程序沒(méi)有外部依賴(lài),可以直接運(yùn)行,所以缺點(diǎn)就是導(dǎo)致目標(biāo)程序的體積增大。
    **(2)動(dòng)態(tài)庫(kù) **:它也是你的.m文件編譯而成的二進(jìn)制文件集合,需要配合暴漏在外面的.h文件使用,但是不同的是,在編譯時(shí)動(dòng)態(tài)庫(kù)不會(huì)被copy到目標(biāo)程序中,目標(biāo)程序只會(huì)存儲(chǔ)指向動(dòng)態(tài)庫(kù)的引用,等到程序運(yùn)行時(shí),動(dòng)態(tài)庫(kù)才會(huì)被真正加載進(jìn)來(lái)。不會(huì)影響目標(biāo)程序的體積,但是會(huì)帶來(lái)一部分性能損失。而且目前蘋(píng)果不允許自制的動(dòng)態(tài)庫(kù)上架到AppStore

  • ** 使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的好處 **
    **(1)靜態(tài)庫(kù) **:模塊化,可以避免少量改動(dòng)經(jīng)常導(dǎo)致大量的重復(fù)編譯連接,也可以重用,但注意不是共享使用。
    **(2)動(dòng)態(tài)庫(kù) **:可以將最終的可執(zhí)行文件體積縮小,多個(gè)應(yīng)用程序共享內(nèi)存中的同一份庫(kù)文件,達(dá)到節(jié)約資源的效果,也可以不重新編譯連接可執(zhí)行程序的前提下,更新動(dòng)態(tài)庫(kù)文件達(dá)到更新應(yīng)用程序的目的。但是可悲的是蘋(píng)果不允許自制的動(dòng)態(tài)庫(kù)上架到AppStore,但是可以開(kāi)發(fā)公司內(nèi)部的應(yīng)用程序還是比較方便的。

創(chuàng)建靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)

下面我們就先分別創(chuàng)建靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),然后將我們創(chuàng)建的靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)應(yīng)用到我們的項(xiàng)目中,這樣便于大家更好的理解靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),也方便大家更好的構(gòu)建自己的項(xiàng)目或框架


** 說(shuō)明 **:我寫(xiě)一個(gè)小Demo,Demo的功能是改變UIImage的顏色,我會(huì)分別創(chuàng)建靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)來(lái)實(shí)現(xiàn)不同的功能模塊(當(dāng)然,都可以創(chuàng)建為靜態(tài)庫(kù),但是為了讓大家更清楚兩種庫(kù)的創(chuàng)建步驟)
(1)靜態(tài)庫(kù):封裝資源文件(.bundle文件)用來(lái)存放圖片,封裝返回圖片路徑的方法并提供外界 .h 文件
(2)動(dòng)態(tài)庫(kù):封裝改變UIimage的顏色的方法并提供外界 .h 文件。

** 順便說(shuō)一下Bundle文件,Bundle文件是靜態(tài)的,也就是說(shuō),我們包含到包中的資源文件作為一個(gè)資源包是不參加項(xiàng)目編譯的。也就意味著,bundle包中不能包含可執(zhí)行的文件。它僅僅是作為資源,被解析成為特定的2進(jìn)制數(shù)據(jù)。**


  • ** (1)創(chuàng)建靜態(tài)庫(kù) **
    第一步:打開(kāi)Xcode,會(huì)彈出下面的選擇框,然后大家選擇標(biāo)記處,然后為靜態(tài)庫(kù)命名并創(chuàng)建。
(1)

創(chuàng)建成功后大家可以看到,Products下的libStaticLibraryTest.a文件是紅色的,不要方,command+B編譯或者run一下就好了,靜態(tài)庫(kù)是程序編譯是copy到目標(biāo)程序中的。如下圖,系統(tǒng)已經(jīng)為我們創(chuàng)建好了一個(gè)以工程名命名的 .h 和 .m 文件。你可以用也可以不用,我就直接用了


(2)

第二步:創(chuàng)建一個(gè)Bundle文件,command+N就會(huì)彈出下面的選擇框,然后選擇標(biāo)記并命名創(chuàng)建
![Uploading 屏幕快照 2016-11-17 上午1.06.21_068118.png . . .]

(3)

如下圖,Bundle文件創(chuàng)建成功后,我向其中放入一張圖片


(4)

第三步:添加Bundle文件到Copy File中,targets -> build phases -> copy files,如下圖所示

(5)

第四步:寫(xiě)相關(guān)方法

(1)在StaticLibraryTest.h提供對(duì)外方法接口

#import <Foundation/Foundation.h>

@interface StaticLibraryTest : NSObject

+ (NSString *)getImagePathWithBundleName:(NSString *)bundleName ImageName:(NSString *)imageName Type:(NSString *)type;

@end

(2)在StaticLibraryTest.m中實(shí)現(xiàn)方法

#import "StaticLibraryTest.h"

@implementation StaticLibraryTest

+ (NSString *)getImagePathWithBundleName:(NSString *)bundleName ImageName:(NSString *)imageName Type:(NSString *)type {
    
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"];
    NSString *path = [NSString stringWithFormat:@"%@/%@.%@", bundlePath, imageName, type];
    return path;
    
}

@end

第五步:執(zhí)行程序,command+R,這樣我們的靜態(tài)庫(kù)就生成好了,點(diǎn)擊libStaticLibraryTest.a,然后show in fender,我們會(huì)看到下面我們生成了針對(duì)于模擬器的靜態(tài)庫(kù),注意我們command+R是在模擬器中run的,如果想生成針對(duì)真機(jī)的靜態(tài)庫(kù),必須在真機(jī)下run,然后可以通過(guò)lipo -create -output命令在終端合并兩個(gè)靜態(tài)庫(kù)文件,這樣我們就得到一個(gè)既可以在真機(jī)又可以在模擬器上使用的靜態(tài)庫(kù)了(這里不多說(shuō)了)。應(yīng)用時(shí)我們就將標(biāo)記處copy到我們的項(xiàng)目中,就可以直接使用了

(6)
  • ** (2)創(chuàng)建動(dòng)態(tài)庫(kù) **

第一步:打開(kāi)Xcode,會(huì)彈出下面的選擇框,然后大家選擇標(biāo)記處,然后為靜態(tài)庫(kù)命名并創(chuàng)建。

(7)

創(chuàng)建完成后如圖所示

(8)

第二步:創(chuàng)建一個(gè)ChangeImageColor類(lèi),用來(lái)寫(xiě)改變圖片顏色的方法

ChangeImageColor.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface ChangeImageColor : NSObject

+ (UIImage *)changeImageColorWithColor:(UIColor *)color Image:(UIImage *)image;

@end

ChangeImageColor.m

#import "ChangeImageColor.h"

@implementation ChangeImageColor

+ (UIImage *)changeImageColorWithColor:(UIColor *)color Image:(UIImage *)image
{
    
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, image.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, kCGBlendModeNormal);
    CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
    CGContextClipToMask(context, rect, image.CGImage);
    [color setFill];
    CGContextFillRect(context, rect);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
    
}

@end

第三步:設(shè)置開(kāi)放的頭文件可以通過(guò)target—>build phases—>headers來(lái)設(shè)置,如下圖

(9)

同時(shí)可以在DynamicLibraryTest.h中倒入自己創(chuàng)建類(lèi)的頭文件


(10)

第四步:通用動(dòng)態(tài)庫(kù)
** 經(jīng)過(guò)以上三步我們只是創(chuàng)建了一個(gè)動(dòng)態(tài)庫(kù)文件,但是和靜態(tài)庫(kù)類(lèi)似,該動(dòng)態(tài)庫(kù)并同時(shí)不支持真機(jī)和模擬器,可以通過(guò)以下步驟創(chuàng)建通用動(dòng)態(tài)庫(kù) **

  • 創(chuàng)建Aggregate,并命名創(chuàng)建。
(11)
  • 設(shè)置Target Dependencies,targets -> Common -> Build Phases -> Target Dependencies,將動(dòng)態(tài)庫(kù)添加到Target Dependencies中
(12)
  • 添加Run Script
(13)
  • 添加腳本,復(fù)制粘貼就好
# Sets the target folders and the final framework product.
# 如果工程名稱(chēng)和Framework的Target名稱(chēng)不一樣的話,要自定義FMK_NAME,否則不需要改動(dòng)
FMK_NAME=${PROJECT_NAME}

# Install dir will be the final output to the framework.
# The following line create it in the root folder of the current project.
INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework

# Working dir will be deleted after the framework 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 binary files (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}"

腳本添加完后,command+B執(zhí)行程序即可,在show in finder找到我們生成的動(dòng)態(tài)庫(kù),如圖,同樣我也只生成了模擬器的動(dòng)態(tài)庫(kù),和靜態(tài)庫(kù)原理相同,可通過(guò)終端來(lái)合成真機(jī)和模擬器共用的動(dòng)態(tài)庫(kù)

(14)

應(yīng)用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)

通過(guò)以上步驟我們已經(jīng)分別生成了靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù),接下來(lái)我們就開(kāi)始運(yùn)用了,很簡(jiǎn)單,一步一步來(lái)就好.

  • 第一步:創(chuàng)建一個(gè)工程,這里多說(shuō)了。
  • 第二部:將靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)copy到工程中,添加后如圖所示
(15)

** 但是這時(shí)候需要注意了,靜態(tài)庫(kù)copy到文件中可以直接使用,但是對(duì)動(dòng)態(tài)庫(kù)必須添加依賴(lài)路徑**

  • 第三步:添加完動(dòng)態(tài)庫(kù)后,同時(shí)設(shè)置將framework作為資源文件拷貝到Bundle中,Targets-->Build Phases-->Copy Bundle Resources,如下圖所示,
(16)

** 好了現(xiàn)在我們就將靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)copy到了我們的工程中,這時(shí)我們就可以使用了。**

項(xiàng)目實(shí)戰(zhàn)

接下來(lái)我在工程中的 ViewController.m 文件中代碼如下

#import "ViewController.h"

// 引入靜態(tài)庫(kù)中文件
#import "StaticLibraryTest.h"

// 引入動(dòng)態(tài)庫(kù)
#import <DynamicLibraryTest/DynamicLibraryTest.h>

@interface ViewController ()

@property (nonatomic, strong) UIImageView *imageOfTest;

@property (nonatomic, strong) UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    [self createSubView];
    
}



- (void)createSubView {
    
    
    self.imageOfTest = [[UIImageView alloc] initWithFrame:CGRectMake((self.view.frame.size.width - 50) / 2, 200, 50, 50)];
    
    // 靜態(tài)庫(kù)中提供的方法
    NSString *imagePath = [StaticLibraryTest getImagePathWithBundleName:@"Resource" ImageName:@"advantage" Type:@"png"];
    self.imageOfTest.image = [UIImage imageWithContentsOfFile:imagePath];
    
    [self.view addSubview:self.imageOfTest];
    
    self.button = [[UIButton alloc] initWithFrame:CGRectMake(20, 450, self.view.frame.size.width - 40, 50)];
    self.button.backgroundColor = [UIColor cyanColor];
    [self.button setTitle:@"change color" forState:UIControlStateNormal];
    [self.view addSubview:self.button];
    [self.button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    
    
}

- (void)buttonAction:(UIButton *)button {
    
    NSLog(@"改變顏色");
    
    UIImage *image = nil;
    // 利用動(dòng)態(tài)庫(kù)中提供方法實(shí)現(xiàn)
    if (button.selected == NO) {
        image = [ChangeImageColor changeImageColorWithColor:[UIColor blueColor] Image:self.imageOfTest.image];
    }
    else {
        image = [ChangeImageColor changeImageColorWithColor:[UIColor blackColor] Image:self.imageOfTest.image];
    }
    self.imageOfTest.image = image;
    
    button.selected = !button.selected;
    
}

總結(jié)

這次博客寫(xiě)的長(zhǎng)了點(diǎn),也許不會(huì)有太好的閱讀效果,本來(lái)想拆分著寫(xiě)了,但是總感覺(jué)那樣對(duì)技術(shù)的提高不算大。希望大家諒解。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容