0

私の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ステートメントから設定されていることを理解しないのはなぜですか?

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 に答える