動態庫與靜態庫(二)

庫與庫的連接有下列四種形式,下面分別進行項目演示:c++

動態庫連接動態庫

App連接動態庫,動態庫連接AFNetworking 1.建立工程MyApp 2.添加一個Target,選擇Frameworkmarkdown

圖片.png 3.在MyApp目錄下建立Podfile,在target 'MyDylib' do下添加以下代碼:ui

target 'MyDylib' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MyDylib
  pod 'AFNetworking'

end
複製代碼

4.從新使用xcworkspace打開項目,在MyDylib添加文件:spa

圖片.png

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyDyLibTest : NSObject
-(void)myDyLibTest;
@end

NS_ASSUME_NONNULL_END
複製代碼
#import "MyDyLibTest.h"
#import<AFNetworking.h>
@implementation MyDyLibTest
-(void)myDyLibTest
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"myDyLibTest===%@",manager);
}
@end
複製代碼

5.將頭文件拖到指定位置3d

圖片.png 6.ViewController.m中添加調用代碼:code

#import "ViewController.h"
#import <MyDylib/MyDyLibTest.h>

@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyDyLibTest *libTest = [MyDyLibTest new];
    [libTest myDyLibTest];
    
    // Do any additional setup after loading the view.
}


@end
複製代碼

7.Scheme選擇MyApp運行工程orm

圖片.png

提示的信息說明了,按照MyDylib保存的@rpath路徑找,找不到AFNetworking圖片

動態庫MyDylibApp正常連接,可是動態庫AFNetworking並不在動態庫MyDylib保存的@rpath與動態庫AFNetworkinginstall_name的組合路徑下ip

動態庫AFNetworking的路徑 = MyDylib@rpath + 動態庫AFNetworkinginstall_nameget

解決方法有兩種分別是:

  • 第一種是拷貝到動態庫AFNetworking到指定路徑下。

在主工程target添加pod 'AFNetworking'從新pod一下。 這種方式能解決問題是由於在Pods-MyApp-frameworks.sh這個文件中,已經經過腳本進行拷貝了

if [[ "$CONFIGURATION" == "Debug" ]]; then
  install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
  install_framework "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework"
fi
複製代碼
  • 第二種是修改動態庫MyDylib@rpath爲動態庫AFNetworkinginstall_name以前的絕對路徑

圖片.png

${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
複製代碼

經過以上兩種方式都可以解決問題。

圖片.png

動態庫反向調用App代碼

1.建立App項目的類,並作相關配置

圖片.png

圖片.png

圖片.png 2.動態庫調用App代碼

#import "MyDyLibTest.h"
#import<AFNetworking.h>
#import "MyAppClass.h"
@implementation MyDyLibTest
-(void)myDyLibTest
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"myDyLibTest===%@",manager);
    
    MyAppClass *cls = [MyAppClass new];
    NSLog(@"MyAppClass===%@",cls);
}
@end
複製代碼

3.遠行項目報錯

圖片.png 解決辦事是告訴連接器動態查找。使用xcconfig配置:

在動態庫MyDyLib下建立

圖片.png

圖片.png

圖片.png

本身建立的xcconfig文件中導入Pod建立的xcconfig文件

圖片.png 可以使用如下參數:

-undefined

圖片.png 這種方式有個問題,就是其它爲定義的符號都不會報錯

-U symbol_name

圖片.png 這種方式只是針對指定符號,忽略報錯信息 修改後運行項目:

圖片.png

App調用動態庫AFNetworking代碼

  • 第一種方式就是直接讓MyApp工程下podAFNetworking
  • 第二種方式是經過設置FRAMEWORK_SEARCH_PATHS

圖片.png

${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
複製代碼

動態庫連接靜態庫

1.配置工程和上一個例子基本同樣,不一樣的是在Podfile是使用靜態庫

target 'MyDyLib' do
  # Comment the next line if you don't want to use dynamic frameworks
  # use_frameworks!

  # Pods for MyDyLib
 pod 'AFNetworking'
end
複製代碼

use_frameworks!前面的#號不能去掉 2.ViewController.m代碼以下:

#import "ViewController.h"
#import <MyDyLib/MyDyLib.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyDyLibTest *libTest = [MyDyLibTest new];
    [libTest myDyLibTest];
}
複製代碼

直接可以運行成功

圖片.png 緣由是在編譯動態庫的時候會把它依賴的靜態庫連接到動態庫中,因此不會報錯

3.App使用靜態庫裏的代碼

#import "ViewController.h"
#import <MyDyLib/MyDyLib.h>
#import <AFNetworking/AFNetworking.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyDyLibTest *libTest = [MyDyLibTest new];
    [libTest myDyLibTest];
    
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"myDyLibTest===%@",manager);
}
複製代碼

圖片.png 頭文件找不到,須要配置一下Header Search Paths

圖片.png 配置完成後,運行

圖片.png

靜態庫連接靜態庫

1.配置工程,參照前兩個配置,建立靜態庫的時候修改一下這個地方

圖片.png 2.相關代碼: MyStaticLibTest代碼:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyStaticLibTest : NSObject
-(void)testMyStaticLib;
@end

NS_ASSUME_NONNULL_END

複製代碼
#import "MyStaticLibTest.h"
#import <AFNetworking/AFNetworking.h>
@implementation MyStaticLibTest
-(void)testMyStaticLib
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"testMyStaticLib===%@",manager);
}
@end

複製代碼

ViewController.m代碼

#import "ViewController.h"
#import <MyStaticLib/MyStaticLib.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyStaticLib *lib = [MyStaticLib new];
    [lib testMyStaticLib];
}
@end
複製代碼

3.遠行報錯

圖片.png

分析:App去連接靜態庫的時候是沒有問題的,可是當靜態庫去鏈家靜態庫AFNetworking的時候,會有問題。由於這個靜態庫AFNetworking並無合併到我本身建立的靜態庫中,App不知道它在哪。 解決方式:

  • 告訴App,靜態庫AFNetworking在哪

圖片.png

${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
複製代碼

配置完成後遠行程序 圖片.png

靜態庫連接動態庫

1.工程配置,參考以上配置 2.相關代碼: MyStaticLibTest代碼:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyStaticLibTest : NSObject
-(void)testMyStaticLib;
@end

NS_ASSUME_NONNULL_END
複製代碼
#import "MyStaticLibTest.h"
#import <AFNetworking/AFNetworking.h>
@implementation MyStaticLibTest
-(void)testMyStaticLib
{
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    NSLog(@"testMyStaticLib===%@",manager);
}
@end
複製代碼

ViewController.m代碼:

#import "ViewController.h"
#import <MyStaticLib/MyStaticLib.h>
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
    [super viewDidLoad];
    MyStaticTest *lib = [MyStaticTest new];
    [lib testMyStaticTest];
}
@end
複製代碼

3.運行報錯

圖片.png

告訴App動態庫AFNetworking在哪

圖片.png

又出現了熟悉的錯誤

圖片.png 這個路徑下找不到動態庫AFNetworking,按照提示路徑進去看一下

圖片.png 缺乏了上面紅色顏色的庫

4.使用腳本將動態庫AFNetworking拷貝到當前路徑下

podAFNetworking動態庫中的項目中拷貝一個以.sh結尾的文件,放到項目根目錄

圖片.png

Run Script內配置正確的路徑

圖片.png 圖片.png

5.編譯運行

圖片.png 已經拷貝過來了,也正常運行了

圖片.png

靜態庫生成的時候只保存了動態庫的名稱,App連接靜態庫後,會把靜態庫全部的代碼都連接進去,可是App不知道動態庫的位置。

相關文章
相關標籤/搜索