69 votes

Equivalent iOS / Objective-C de la AsyncTask d'Android

Je connais bien l'utilisation de AsyncTask dans Android: créez une sous-classe, appelez execute sur une instance de la sous-classe et onPostExecute est appelé sur le thread ou la main de l'interface utilisateur. fil. Quel est l'équivalent dans iOS?

102voto

iamataptool Points 3410

Grand central dispatch a une façon similaire de l'exécution de tâches en arrière-plan. Pour effectuer quelque chose de manière asynchrone, il vous suffit de créer une file d'attente (comme un fil) et passer ensuite un bloc pour être exécuté en arrière-plan.

dispatch_queue_t queue = dispatch_queue_create("com.yourdomain.yourappname", NULL);
dispatch_async(queue, ^{
    //code to be executed in the background
});

La documentation a beaucoup plus d'informations sur le sujet si vous êtes si incliné.

Edit 1:

Si vous souhaitez effectuer une tâche en arrière-plan et la mise à jour de l'INTERFACE utilisateur (ou de faire quelque chose sur un autre thread) quand c'est fait, vous pouvez imbriquer l'envoi des appels de la sorte:

dispatch_queue_t queue = dispatch_queue_create("com.yourdomain.yourappname", NULL);
dispatch_async(queue, ^{
    //code to be executed in the background
    dispatch_async(dispatch_get_main_queue(), ^{
        //code to be executed on the main thread when background task is finished
    });
});

Edit 2:

Lors de la création d'une file d'attente, vous pouvez également utiliser l' dispatch_get_global_queue() fonction pour obtenir une expédition de la file d'attente avec une certaine priorité (comme DISPATCH_QUEUE_PRIORITY_HIGH). Ces files d'attente sont accessibles à tous et sont utiles lorsque vous souhaitez affecter des tâches multiples pour le même thread/file d'attente.

18voto

MansApps Points 219

Il n'y a pas de classes pour que en iOS, mais vous pouvez simuler en utilisant des files d'attente. Vous pouvez appeler:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Your code to execute in background...
});

pour async tâches et à l'intérieur de votre async code de l'appel suivant de la file d'attente pour faire quelque chose dans la vue...:

dispatch_async(dispatch_get_main_queue(), ^{
    //Your code to execute on UIthread (main thread)
});

Puis, à l'aide de deux files d'attente, vous pouvez créer une classe asyncTask, ajouter cette classe de votre projet, afin de les mettre en œuvre:


//
//  AsyncTask.h
//  Staff5Personal
//
//  Created by Mansour Boutarbouch Mhaimeur on 25/10/13.
//  Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface AsyncTask : NSObject

- (void) executeParameters: (NSArray *) params;
- (void) preExecute;
- (NSInteger) doInBackground: (NSArray *) parameters;
- (void) postExecute: (NSInteger) result;
@end

//
//  AsyncTask.m
//  Staff5Personal
//
//  Created by Mansour Boutarbouch Mhaimeur on 25/10/13.
//  Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//

#import "AsyncTask.h"

@implementation AsyncTask

- (void) executeParameters: (NSArray *) params{
    [self preExecute];
    __block NSInteger result;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        result = [self doInBackground:params];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self postExecute:result];
        });
    });
}

- (void) preExecute{
    //Method to override
    //Run on main thread (UIThread)
}

- (NSInteger) doInBackground: (NSArray *) parameters{
    //Method to override
    //Run on async thread (Background)
    return 0;
}

- (void) postExecute: (NSInteger) result{
    //Method to override
    //Run on main thread (UIThread)
}

@end

C'est un exemple que j'utilise dans un projet:


//
//  SendChatTask.h
//  Staff5Personal
//
//  Created by Mansour Boutarbouch Mhaimeur on 25/10/13.
//  Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//

#import "AsyncTask.h"
#import "Chat.h"

@interface SendChatTask : AsyncTask{
    NSArray *chatsSinEnviar;
}

@end

//
//  SendChatTask.m
//  Staff5Personal
//
//  Created by Mansour Boutarbouch Mhaimeur on 25/10/13.
//  Copyright (c) 2013 Smart & Artificial Technologies. All rights reserved.
//

#import "SendChatTask.h"

@implementation SendChatTask

- (void) preExecute{
    //Method to override
}

- (NSInteger) doInBackground: (NSArray *) parameters{
    //Method to override
    NSString *sendChatsURL = [NSString stringWithFormat:@"%@%@%@",HOST, NAMESPACE,URL_SEND_CHAT];
    chatsSinEnviar = [parameters objectAtIndex:0];

    NSString *respuesta;
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    NSUserDefaults *session = [NSUserDefaults standardUserDefaults];
    NSString *userName = [session stringForKey:@"userName"];
    [params setObject:userName forKey:@"username"];
    [params setObject:[NSString stringWithFormat:@"%d", [[chatsSinEnviar objectAtIndex:0] id]] forKey:@"id"];
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[ChatJSONParser wrapChatArray:chatsSinEnviar] options:0 error:&error];
    NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];

    [params setObject:JSONString forKey:@"chats"];

    respuesta = [HTTPClient executePOST:sendChatsURL parameters:params];

    if([respuesta isEqualToString:@"true"]){
        return 1;
    }else{
        return -1;
    }
}

- (void) postExecute: (NSInteger) result{
    //Method to override
    if (result == 1) {
        for (Chat *chat in chatsSinEnviar) {
            chat.estado = ESTADO_ENVIADO;
            [chat save];
            AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
            [appDelegate refreshChat];
        }
    } else {

    }
}

@end

Et l'appel suivant:

[[[SendChatTask alloc] init] executeParameters:[NSArray arrayWithObjects: chatsNoEnviados, nil]];

Vous pouvez ajouter un publishProgress() méthode de mise à jour et... je ne l'utilise pas pour le moment car j'ai appeler mon async tâche en arrière-plan.

J'espère que c'est utile.

5voto

JeanLuc Points 1442

si votre ciblage plus tôt, la Version iOS (que l'iOS 4 pour Grand Central Dispatch), vous pouvez utiliser le NSObject performSelector méthodes

Ceci est un exemple:

[self performSelectorInBackground:@selector(executeInBackground) withObject:nil];


-(void) executeInBackground
{
    NSLog(@"executeInBackground");

    [self performSelectorOnMainThread:@selector(executeOnMainThread) withObject:nil waitUntilDone:NO];
}

-(void) executeOnMainThread
{
    NSLog(@"executeOnMainThread");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X