iOS dlopen 動態加載Frameworks

本文以播放音樂為例演示動態加載:

正常播放音樂

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

本動態加載方法應該也適用加載私有庫并適用其中的方法,暫時沒有測試,另找時間測試,后面再更新。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容