1

ときどきこのクラッシュが発生しますが、これを再現するのは非常に困難です。

0   CoreFoundation                  0x39ff73e2 __exceptionPreprocess + 158
1   libobjc.A.dylib                 0x3905095e objc_exception_throw + 26
2   CoreFoundation                  0x39ffaf2c -[NSObject(NSObject) doesNotRecognizeSelector:] + 180
3   CoreFoundation                  0x39ff9648 ___forwarding___ + 388
4   CoreFoundation                  0x39f51204 _CF_forwarding_prep_0 + 20
5   Foundation                      0x32914bec -[NSDictionary(NSKeyValueCoding) valueForKey:] + 28
6   MyAppName                       0x00032112 -[myViewController stopPlayersWithVolume:] (myViewController.m:151)

このコードから:

- (void)stopPlayersWithVolume:(double)volume
{
    for (NSString *file in players)
    {
        AVAudioPlayer *player = [players valueForKey:file];
        if (player.volume == volume || volume == 0)
            [player stop];
    }
}

playersNSMutableDictionaryプロパティでself.あり、ARCで必要とは思わないため、アクセスせずにアクセスします。キーはファイル名(「mysound.mp3」など)であり、値はAVAudioPlayerオブジェクトです。

スタックトレースは、file渡したパラメーター[NSMutableDictionary valueForKey]が実際にはではなくNSString、したがって認識されないセレクターではないことを示していますか?ディクショナリを介した高速な列挙から予想されるように、これは常にNSStringデバッガー内にありますが、デバッガーでクラッシュが発生することはありません。

私の唯一の考えは、辞書を破壊するスレッドの問題があるということです。上記のコードはNSTimerによって起動されていますが、これは実行ループを介した単なるメッセージであり、個別のスレッドではないため、クロススレッドアクセスについて心配する必要はないと思いますか?

任意の提案をいただければ幸いです。これを捨てて申し訳ありませんが、私は立ち往生しています。

編集:

プレーヤー辞書は次のように割り当てられviewDidLoadます。

players = [[NSMutableDictionary alloc] init];

そして、次のように宣言されています:

@property (retain, nonatomic) NSMutableDictionary *players;

そして次のように合成されます:

@synthesize players;
4

2 に答える 2

1

players辞書またはその内容を繰り返し処理しているときに、辞書またはその内容の割り当てが解除されている可能性があります。NSZombiesをオンにして、デバッガーでクラッシュを再現してみてください。割り当てが解除されているオブジェクトに関する詳細情報が表示されます。

于 2012-12-14T12:36:36.197 に答える
0

辞書を割り当てる(そしてオーディオを設定する)コードは次のようになりました。

NSError *error = [[NSError alloc] init];
NSArray *names = [fm contentsOfDirectoryAtPath:resourcePath error:&error];
players = [[NSMutableDictionary alloc] init];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&error];
[[AVAudioSession sharedInstance] setActive:YES error:&error];

NSError問題が発生する可能性はほとんどありませんが、私が知る限り、その使用は間違っているので、どこかからコピーして貼り付けたに違いありません。コードを次のように変更しました。

NSArray *names = [fm contentsOfDirectoryAtPath:resourcePath error:nil];
players = [[NSMutableDictionary alloc] init];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];

そして問題はなくなります、それは現れます。100%確実ではありませんが、前者のコードでは10回の試行でクラッシュを再現でき、後者では再現できません。理由はわかりません。

于 2012-12-14T14:49:34.613 に答える