向NSMutableArray添加对象时抛出EXC_BAD_ACCESS

时间:2012-12-31 01:10:45

标签: ios nsmutablearray exc-bad-access

尝试将对象添加到数组时出现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 on the method。

因此,如何初始化数组或对象类型一定存在问题,但我无法弄明白。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:4)

您无法向float添加NSArray。你必须将它包装在NSNumber

但是

真正的问题是传入的第一个参数是您创建的NSArray,传递给函数的第二个参数是支持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]];

请注意,这将被视为一个非常奇怪的功能,但此代码确实运行。