动态库与静态库(二)

库与库的链接有下列四种形式,下面分别进行项目演示:

动态库链接动态库

App链接动态库,动态库链接AFNetworking
1.创建工程MyApp
2.添加一个Target,选择Framework

图片.png
3.在MyApp目录下创建Podfile,在target 'MyDylib' do下添加如下代码:

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添加文件:

图片.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.将头文件拖到指定位置

图片.png
6.ViewController.m中添加调用代码:

#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运行工程

图片.png

提示的信息说明了,按照MyDylib保存的@rpath路径找,找不到AFNetworking

动态库MyDylibApp正常链接,但是动态库AFNetworking并不在动态库MyDylib保存的@rpath与动态库AFNetworkinginstall_name的组合路径下

动态库AFNetworking的路径 = MyDylib@rpath + 动态库AFNetworkinginstall_name

解决方法有两种分别是:

  • 第一种是拷贝到动态库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不知道动态库的位置。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享