iOS在if-else语句后使用未声明的标识符

时间:2011-09-21 05:05:11

标签: ios undeclared-identifier

我有这段代码可以在我的iphone上播放我的mp3文件并且有效:

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];
}

唯一正在改变的行是NSString * url。当我尝试执行以下操作来清理我的代码时,我收到“使用未声明的标识符'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];

为什么NSURL不理解NSString * url是从上面的if-else语句设置的?

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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];

答案 2 :(得分: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];