库与库的链接有下列四种形式,下面分别进行项目演示:
动态库链接动态库
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不知道动态库的位置。