【问题标题】:this app was developed and works fine under ios 5.0, but crashes under ios 4.3这个应用程序是在 ios 5.0 下开发并运行良好,但在 ios 4.3 下崩溃
【发布时间】:2012-01-13 21:30:45
【问题描述】:

我在 iOS 5.0 下开发了一个 iPhone 应用程序,它运行良好。但是当涉及到 iOS 4.3(Base SDK = latest iOS 5.0, compiler = Apple LLVM 3.0, Deployment Target = iOS 4.3)时,它在启动后崩溃。

崩溃点附近的输出如下所示:

2011-12-06 16:25:08.177 FMWei[466:c203] -[AVAudioSession setMode:error:]: unrecognized selector sent to instance 0x706a7f0
2011-12-06 16:25:08.181 FMWei[466:c203] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[AVAudioSession setMode:error:]: unrecognized selector sent to instance 0x706a7f0'

看起来AVAudioSession 在我调用它时没有成员函数setMode:error:。但奇怪的是,我没有调用名为setMode:error: 的函数。关于音频处理的代码是:

audio_session = [[AVAudioSession sharedInstance] retain];
audio_session_err = nil;
[audio_session setCategory: AVAudioSessionCategoryPlayAndRecord error:&audio_session_err];
NSLog(@"!");

UInt32 audioRouteOverride = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,sizeof (audioRouteOverride),&audioRouteOverride);
UInt32 allowMixing = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);    

if (audio_session_err) 
{
    NSLog(@"audioSession: %@ %d %@", [audio_session_err domain], [audio_session_err code], [audio_session_err description]);
}
else
{
    audio_session_err = nil;
    [audio_session setActive:YES error:&audio_session_err];
    if (!audio_session_err) NSLog(@"audio session is activated successfully");
}

请帮我弄清楚为什么它在 iOS 4.3 下崩溃并出现奇怪的错误。谢谢!

【问题讨论】:

    标签: iphone ios crash avaudiosession


    【解决方案1】:

    在运行时,调用了许多不在您的代码中的方法,但由于您进行的 API 调用而在幕后调用了这些方法。

    我不会关注被调用的方法,而是关注它被发送到的对象为什么无法响应选择器。该对象可能被转换为错误的类型,因此没有继承正确的方法。 (在您显示的代码 sn-p 中,您没有显式转换 AVAudioSession *audio_session。)另一个方向是检查您是否没有使用仅 iOS 5 的其他 API 调用,它在后台调用它方法,从而产生错误。

    最后,如果您最近才将构建目标更改为包含 iOS 4.3,您可能只需要进行干净构建(产品 > 清洁),以便编译与 iOS 4.3 兼容的代码。

    【讨论】:

    • 谢谢邓肯:-) .h 文件中有一个NSError *audio_session_err;
    • 我在 .h 文件中投射了 AVAudioSession *audio_session;,很抱歉我没有显示。
    • 我包含的 AVFoundation.framework 文件是否可能仅适用于 iOS 5.0,并且它会调用一些不友好的东西?如何包含这些框架的旧版本?
    • 嗯,这提出了一个有趣的可能性。如果您最近才将应用更改为将 iOS 4.3 作为构建目标,请尝试干净的构建...
    • 太棒了...不知道该说什么,我很愚蠢...请修改答案,我会接受。
    【解决方案2】:

    或许你可以试试下面的代码sn-p

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&sessionError];
    NSError * audio_session_err = nil;
    [audio_session setCategory: AVAudioSessionCategoryPlayAndRecord error:&audio_session_err];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&audio_session_err];
    [[AVAudioSession sharedInstance] setDelegate:self];
    NSLog(@"!");
    
    UInt32 audioRouteOverride = 1;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,sizeof (audioRouteOverride),&audioRouteOverride);
    UInt32 allowMixing = 1;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);    
    
    if (audio_session_err) {
      NSLog(@"audioSession: %@ %d %@", [audio_session_err domain], [audio_session_err code], [audio_session_err description]);
    } else {
      audio_session_err = nil;
      [[AVAudioSession sharedInstance] setActive:YES error:&audio_session_err];
      if (!audio_session_err) NSLog(@"audio session is activated successfully");
    }
    

    我认为audio_session = [[AVAudioSession sharedInstance] retain]; 默认调度方法setMode:。而setMode: 仅适用于 iOS 5.0 及更高版本(请参阅Doc)。

    或者你可以尝试注释掉代码:

    UInt32 audioRouteOverride = 1;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,sizeof (audioRouteOverride),&audioRouteOverride);
    UInt32 allowMixing = 1;
    AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
    

    必须有一个方法默认调度setMode:。自己试试。 :p


    在您的 gdb 中尝试info malloc 0x706a7f0 以获取选择器发送到的对象。请注意,0x706a7f0 是在您的崩溃输出中显示为您的第一个代码 sn-p 中的地址。

    还有一个提示,您可以使用make clean(Poduct->Clean) 和rebuild 它。

    【讨论】:

    • @Skyler 也许你不应该保留[AVAudioSession sharedInstance]。看HERE ;)
    • 谢谢:-) 我试过不保留它,但它还是崩溃了。
    • 我试了你的sn-p,也把刚才的C代码注释掉了。它崩溃并出现相同的错误:-(
    • 嗨@Skyler,我看到你在你的代码中添加了一些NSLog。能否显示应用崩溃前打印的内容?
    • 谢谢@Kjuly,目标在崩溃前什么也没输出。它看起来像是在运行前崩溃了,因为我在AppicationDidFinishLaunching 中有几个 NSLog,但仍然没有输出。此外,调试器会输出很多关于“比可执行时间戳更新”或“无法打开 OSO 文件以扫描 objfile 的 pubtypes”的警告
    【解决方案3】:

    AVAudioSession 方法

    - (BOOL)setMode:(NSString *)theMode error:(NSError **)outError
    

    在文档中标记为仅适用于 iOS 5 及更高版本。事实上,鉴于 recent addition of modes to the documentation,在 iOS 5 之前似乎根本不提供音频会话模式。

    【讨论】:

    • 你可以尝试一个符号断点来确定它在你的代码中被调用的位置。
    • 我在-[AVAudioSession setMode:error:] 中添加了一个符号断点,但没有任何改变。它像以前一样崩溃。
    • 符号断点不是为了阻止崩溃,而是为了澄清导致调用该方法的你的代码中的确切行。 :)
    • 嗯......确实它没有澄清任何事情。它看起来像在运行前崩溃了。我在ApplicationDidFinishLaunching 中添加了一些 NSLog,但没有输出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多