iOS越狱设备CLI应用中audioPlayerDidFinishPlaying方法未触发求助
问题分析与修复方案
核心问题点
- 本地文件URL创建错误:
[NSURL URLWithString:@"test.mp3"]仅适用于网络URL,加载本地音频文件必须使用fileURLWithPath,否则无法正确读取文件。 - RunLoop未启动导致回调失效:AVAudioPlayer的代理回调依赖Cocoa RunLoop机制,你用
sleep阻塞主线程的方式会让RunLoop无法处理事件,audioPlayerDidFinishPlaying自然不会被触发。 - 缺失错误检查:初始化播放器时忽略了错误参数,无法排查文件加载、播放器初始化失败等问题。
修复后的代码
#import <Foundation/Foundation.h> #import <AVFoundation/AVFoundation.h> @interface AVAPDelegate: NSObject<AVAudioPlayerDelegate> @end @implementation AVAPDelegate -(void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { NSLog(@"播放完成,状态:%@", flag ? @"成功" : @"失败"); // 播放结束后停止RunLoop,退出程序 CFRunLoopStop(CFRunLoopGetCurrent()); } @end int main(){ @autoreleasepool { AVAPDelegate *dele = [[AVAPDelegate alloc] init]; // 越狱CLI环境建议用绝对路径,替换为你的音频文件实际路径 NSString *filePath = @"/var/mobile/test.mp3"; // 若用相对路径,可尝试:NSString *filePath = [[NSFileManager defaultManager] currentDirectoryPath]; // filePath = [filePath stringByAppendingPathComponent:@"test.mp3"]; NSError *error = nil; AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:&error]; if (!player) { NSLog(@"播放器初始化失败:%@", error.localizedDescription); return 1; } player.delegate = dele; [player prepareToPlay]; BOOL playStarted = [player play]; if (!playStarted) { NSLog(@"播放启动失败"); return 1; } // 启动主线程RunLoop,让代理回调能被处理 CFRunLoopRun(); } return 0; }
额外说明
- 越狱环境下的CLI程序,
NSBundle mainBundle无法正确获取资源路径,必须使用绝对路径指定音频文件位置,比如/var/mobile/Documents/test.mp3。 - 加入
@autoreleasepool管理内存,避免CLI程序出现内存泄漏。 - 用
CFRunLoopRun()启动RunLoop处理回调,播放完成后在代理方法中调用CFRunLoopStop终止程序。
内容的提问来源于stack exchange,提问作者xxTIGERxx
相关产品推荐
相关产品推荐

