本文以播放音樂為例演示動態加載:
正常播放音樂
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