库与库的链接有下列四种形式,下面分别进行项目演示:
动态库链接动态库
App链接动态库,动态库链接AFNetworking
1.创建工程MyApp
2.添加一个Target,选择Framework
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添加文件:
#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.将头文件拖到指定位置
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运行工程
提示的信息说明了,按照MyDylib保存的@rpath路径找,找不到AFNetworking
动态库MyDylib被App正常链接,但是动态库AFNetworking并不在动态库MyDylib保存的@rpath与动态库AFNetworking的install_name的组合路径下
动态库AFNetworking的路径 = MyDylib的@rpath + 动态库AFNetworking的install_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为动态库AFNetworking的install_name之前的绝对路径
${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
通过以上两种方式都能够解决问题。
动态库反向调用App代码
1.创建App项目的类,并做相关配置
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.远行项目报错
解决办事是告诉链接器动态查找。使用
xcconfig配置:
在动态库MyDyLib下创建
自己创建的xcconfig文件中导入Pod创建的xcconfig文件
可使用以下参数:
-undefined
这种方式有个问题,就是其它为定义的符号都不会报错
-U symbol_name
这种方式只是针对指定符号,忽略报错信息
修改后运行项目:
App调用动态库AFNetworking代码
- 第一种方式就是直接让
MyApp工程下podAFNetworking - 第二种方式是通过设置
FRAMEWORK_SEARCH_PATHS
${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];
}
直接能够运行成功
原因是在编译动态库的时候会把它依赖的静态库链接到动态库中,所以不会报错
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);
}
头文件找不到,需要配置一下
Header Search Paths
配置完成后,运行
静态库链接静态库
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];
MyStaticLib *lib = [MyStaticLib new];
[lib testMyStaticLib];
}
@end
3.远行报错
分析:App去链接静态库的时候是没有问题的,但是当静态库去链家静态库AFNetworking的时候,会有问题。因为这个静态库AFNetworking并没有合并到我自己创建的静态库中,App不知道它在哪。
解决方式:
- 告诉App,静态库
AFNetworking在哪
${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/AFNetworking
配置完成后远行程序
静态库链接动态库
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.运行报错
告诉App动态库AFNetworking在哪
又出现了熟悉的错误
这个路径下找不到动态库
AFNetworking,按照提示路径进去看一下
缺少了上面红色颜色的库
4.使用脚本将动态库AFNetworking拷贝到当前路径下
在pod过AFNetworking动态库中的项目中拷贝一个以.sh结尾的文件,放到项目根目录
在Run Script内配置正确的路径
5.编译运行
已经拷贝过来了,也正常运行了
静态库生成的时候只保存了动态库的名称,App链接静态库后,会把静态库所有的代码都链接进去,但是App不知道动态库的位置。