1

オブジェクトを配列に追加しようとすると、EXC_BAD_ACCESS エラーが発生します。これは、メモリに存在しないものを指している、またはオブジェクトに nil 値が含まれていることを意味する可能性があることを理解しています。

コード:

- (void)fadeInPlayer:(AVAudioPlayer *)player withMaxVolume:(float)maxVolume {

NSLog(@"player: %@", player);
NSLog(@"maxVolume: %f", maxVolume);

NSMutableArray *playerAndVolume = [NSMutableArray arrayWithObjects: player, maxVolume, nil];

if (player.volume <= maxVolume) {
    player.volume = player.volume + 0.1;
    NSLog(@"%@ Fading In", player);
    NSLog(@"Volume %f", player.volume);
    [self performSelector:@selector(fadeInPlayer:withMaxVolume:) withObject:playerAndVolume afterDelay:0.5];
    //playerAndVolume array used here because performSelector can only accept one argument with a delay and I am using two...
    }

}

奇妙なことに、コンソールに追加しようとしているオブジェクト (上記の NSLogs として表示) を出力すると、データが返されます。

player: <AVAudioPlayer: 0x913f030>
maxVolume: 0.900000

NSLogs の直後にアプリがクラッシュします。残りのコードは配列がなくても正常に機能しますが、メソッドで performselector:withObject:AfterDelay を呼び出すために配列を使用する必要があります。

したがって、配列の初期化方法、またはオブジェクトの種類に問題があるに違いありませんが、わかりません。

どんな助けでも感謝します。

4

1 に答える 1

4

floatに を追加することはできませんNSArray。でラップする必要がありますNSNumber

しかし

実際の問題は、渡された最初の引数がNSArray作成したものであり、関数に渡された 2 番目のパラメーターがメソッドNSTimerをサポートするものであることです。performSelector:afterDelay:...配列内のオブジェクトを広げません。配列を最初の引数として渡すだけです。APIこの設計に固執する場合は、最初の引数のクラスをテストして、それがNSArrayまたはであるかどうかを確認する必要がありAVAudioPlayerます。この関数は次のように実装できます。

-(void)fadeInPlayer:(AVAudioPlayer *)player withMaxVolume:(NSNumber *)maxVolume {
    if ([player isKindOfClass:[NSArray class]]){
        // This is a redundant self call, and the player and max volume are in the array.
        // So let's unpack them.
        NSArray *context = (NSArray *)player;
        player = [context objectAtIndex:0];
        maxVolume = [context objectAtIndex:1];
    } 

    NSLog(@"fading in player:%@ at volume:%f to volume:%f",player,player.volume,maxVolume.floatValue);

    if (maxVolume.floatValue == player.volume || maxVolume.floatValue > 1.0) return;

    float newVolume =  player.volume + 0.1;
    if (newVolume > 1.0) newVolume = 1.0;
    player.volume = newVolume;

    if (newVolume < maxVolume.floatValue){
        NSArray *playerAndVolume = [NSArray arrayWithObjects: player, maxVolume, nil];
        [self performSelector:@selector(fadeInPlayer:withMaxVolume:) withObject:playerAndVolume afterDelay:0.5];
    }
}

floatこれを使用して、次のNSNumberように で囲みます。

[self fadeInPlayer:player withMaxVolume:[NSNumber numberWithFloat:1.0]];

これは非常に奇妙な関数と見なされることに注意してください。ただし、このコードは実行されます。

于 2012-12-31T01:17:41.050 に答える