0

Hello guys I have a problem ..

I have basically a method that compares you with 3 if that type of letter (letter by letter taken from a label). (If a point, a line or a space). depending on the type launches a code that reproduces a specific sound. the problem I have is that, launched this method, the app freezes until it has finished cycleFor.

I wonder, is there a way to get him to do in the background or in another thread? is enough for me that the user can do something else while is in progress this code.

I can not even with another button that stops the player, how could I do?

I state that I am a novice and I know scarcely what are the thred

Thanks in advance for your help, sorry for the English

This is my code:

-(IBAction)transmitSound:(id)sender {

NSString *code = self.labelCode.text;
//labelCode is the label that contains the code to be translated 


for (int i = 0; i <= [code length]; i++) {
    NSString * ch = [code substringWithRange:NSMakeRange(i, 1)];
    //I need to compare a letter at a time

    if ([ch isEqual:nil]) {nil;}
    //should avoid error .. or is it useless?


    if ([ch isEqual: @"."]) {
 NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
 resourcePath = [resourcePath stringByAppendingString:@"/beepCorto.mp3"];
 player = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL      fileURLWithPath:resourcePath] error:nil];

        [player setDelegate:self];
        [player play];

            NSLog(@"beepCorto");
            sleep(1);
           //aspect 1 seconds because if I don't, you hear nothing

            [player stop];

        }


        else if ([ch isEqual: @"-"]) {

            if (player) {
                if ([player isPlaying]) {
                    [player stop]; } }

            NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
            resourcePath = [resourcePath stringByAppendingString:@"/beepLungo.mp3"];
            player = [[AVAudioPlayer alloc] initWithContentsOfURL: [NSURL fileURLWithPath:resourcePath] error:nil];
            [player setDelegate:self];
            [player play];


            NSLog(@"beepLungo");
            sleep(1);

            [player stop];
        }


        //se trovi un " "  (spazio)
        else if ([ch isEqual: @" "]) {

            if (player) {
                if ([player isPlaying]) {
                    [player stop]; } }

            NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
            resourcePath = [resourcePath stringByAppendingString:@"/silenzio.mp3"];
            player =[ [AVAudioPlayer alloc]initWithContentsOfURL: [NSURL fileURLWithPath:resourcePath] error:nil];
            [player setDelegate:self];
            [player play];


            NSLog(@"silenzio");
            sleep(1);

            [player stop];

        }
    }

}

4

1 に答える 1

0

アプリにフリーズを要求しているため、アプリがフリーズします。問題はこれです:

    [player play];
    NSLog(@"beepCorto");
    sleep(1);
    //aspect 1 seconds because if I don't, you hear nothing
    [player stop];

毎回 1 秒間スリープするようにアプリに指示しています。これは非常に悪いことです。アプリが応答しなくなり、クラッシュする可能性があります。

AVAudioPlayer のデリゲートを使用して、アプリがフリーズするのを防ぐために関数を完全に書き直す必要があります... または、別のスレッドでコードを実行するだけです。

編集:デリゲートを実装するには、次のようにします。

1.- クラスをAVAudioPlayerDelegateプロトコルに準拠させます。これを行うには、宣言を変更します。

@interface MyClass : NSObject <AVAudioPlayerDelegate>

2.- クラスにプロトコルのaudioPlayerDidFinishPlaying:successfully:メソッドを実装させます。

(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    // This function will be called when the 'player' has finished playing
    beepCount ++
    NSString *ch = [code substringWithRange:NSMakeRange(beepCount, 1)];
    // ...
    // Here you can instantiate the next AVAudioPlayer to play the next beep
    // Don't forget to set the delegate again
}

3.- AVAudioPlayer オブジェクト セットを作成するたびに、そのデリゲートが設定さselfれます (既に行っているように)。

再生中のビープ音を追跡するには、クラスに追加の変数を保持する必要があります。上記の例では、変数 beepCount になります (単なる例です。他の方法で処理できます)。

于 2014-02-19T14:58:14.757 に答える