本文以播放音乐为例演示动态加载:
正常播放音乐
1.导入AVFoundation.framework
2.包含头文件 #import <AVFoundation/AVFoundation.h>
3.声明类成员变量
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property (nonatomic,strong) AVAudioPlayer *normal_Player;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self normalPlay];
}
- (void)normalPlay{
NSString *path = [[NSBundle mainBundle] pathForResource:@"rain" ofType:@"mp3"];
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
self.normal_Player = [[AVAudioPlayer alloc] initWithData:data error:nil];
self.normal_Player.numberOfLoops = -1;
[self.normal_Player play];
NSLog(@"正常加载播放");
}
@end
dlopen
函数定义:
void * dlopen( const char * pathname, int mode );
函数描述:
在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。
mode:分为这两种
RTLD_LAZY 暂缓决定,等有需要时再解出符号
RTLD_NOW 立即决定,返回前解除所有未决定的符号。
RTLD_LOCAL
RTLD_GLOBAL 允许导出符号
RTLD_GROUP
RTLD_WORLD
返回值:
打开错误返回NULL
成功,返回库引用
编译时候要加入 -ldl (指定dl库)
动态加载AVFoundation.framework播放音乐
1.不需要导入AVFoundation.framework,导入 #include <dlfcn.h>
2.不需要包含头文件 #import <AVFoundation/AVFoundation.h>
3.声明类成员变量
#import "ViewController.h"
#include <dlfcn.h>
@interface ViewController ()
@property (nonatomic,strong) id runtime_Player;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self runtimePlay];
}
- (void)runtimePlay{
// 获取音乐资源路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"rain" ofType:@"mp3"];
// 加载库到当前运行程序
void *lib = dlopen("/System/Library/Frameworks/AVFoundation.framework/AVFoundation", RTLD_LAZY);
if (lib) {
// 获取类名称
Class playerClass = NSClassFromString(@"AVAudioPlayer");
// 获取函数方法
SEL selector = NSSelectorFromString(@"initWithData:error:");
// 调用实例化对象方法
_runtime_Player = [[playerClass alloc] performSelector:selector withObject:[NSData dataWithContentsOfFile:path] withObject:nil];
// 获取函数方法
selector = NSSelectorFromString(@"play");
// 调用播放方法
[_runtime_Player performSelector:selector];
NSLog(@"动态加载播放");
}
}
@end