0

I have this piece of code which plays my mp3 files on my iphone and it works:

if(i == 1) { 
  NSString *url = [[NSBundle mainBundle]pathForResource:@"fart" ofType:@"mp3"];
  player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:url] error:NULL];
  [player play];
} else if(i==2) {
  NSString *url = [[NSBundle mainBundle]pathForResource:@"fart6" ofType:@"mp3"];
  player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:url] error:NULL];
  [player play];  
} else {
  NSString *url = [[NSBundle mainBundle]pathForResource:@"fart7" ofType:@"mp3"];
  player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:url] error:NULL];
  [player play];
}

The only lines that are changing is the NSString *url. When I try to do the below to clean up my code, I get the error of "use of undeclared identifier 'url'".

if(i == 1) { 
  NSString *url = [[NSBundle mainBundle]pathForResource:@"fart" ofType:@"mp3"];      
} else if(i==2) {
  NSString *url = [[NSBundle mainBundle]pathForResource:@"fart6" ofType:@"mp3"];        
} else {
  NSString *url = [[NSBundle mainBundle]pathForResource:@"fart7" ofType:@"mp3"];      
}

player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:url] error:NULL];
[player play];

Why does NSURL not understand that the NSString *url is set from the above if-else statements?

4

3 回答 3

2

变量声明的范围url开始于声明点(当您编写时NSURL *url),并结束于封闭块的末尾(在 处})。这些声明中的每一个url都在一个块中(介于{和之间}),但您尝试使用的声明在任何包含声明的块之外。url因此,当您尝试使用它时,范围内不再声明标识符。

要修复它,请将声明移出块,然后从块内分配给变量:

NSString *url = nil;
if(i == 1) { 
  url = …;
} else if(i==2) {
  url = …;
} else {
  url = …;
}

player = [[AVAudioPlayer alloc]
    initWithContentsOfURL:[NSURL fileURLWithPath:url] error:NULL];
[player play];

或者:

NSString *url = nil;
switch (i) {
case 1: url = …; break;
case 2: url = …; break;
default: url = …; break;
}

甚至:

NSString *url = (1 == i)? val1 : (2 == i)? val2 : valDefault;
于 2011-09-21T05:11:25.753 回答
2

在 Objective-C(和我知道的其他 C 基础语言)中,每个块都有自己的范围,因此如果您在该范围内声明一个变量,它将不会与包含块共享,但可以从包含块中看到变量包含块。

有点模糊的解释,但这是您需要做的:

NSString *url;
if(i == 1) { 
  url = [[NSBundle mainBundle]pathForResource:@"fart" ofType:@"mp3"];      
} else if(i==2) {
  url = [[NSBundle mainBundle]pathForResource:@"fart6" ofType:@"mp3"];        
} else {
  url = [[NSBundle mainBundle]pathForResource:@"fart7" ofType:@"mp3"];      
}

player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:url] error:NULL];
[player play];
于 2011-09-21T05:12:04.953 回答
2

“变量的范围仅限于声明它们的块”。

if-else块之前声明url 。您仍然可以将代码优化为这样。

NSString *fileName = @"";
if (i == 1) fileName =  @"fart";
else if (i == 2) fileName =  @"fart6";
else fileName =  @"fart7"; 

NSString *path = [[NSBundle mainBundle]pathForResource:fileName ofType:@"mp3"];
NSURL *url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
[player play];
于 2011-09-21T05:13:35.570 回答