iOS/Objective-C相当于Android的AsyncTask

Sun*_*day 68 android asynchronous ios android-asynctask

我熟悉AsyncTaskAndroid中的使用:创建子类,调用子类execute的实例,并onPostExecute在UI线程或主线程上调用.什么是iOS中的等价物?

eri*_*ell 102

回答原始问题:

Grand Central Dispatch(GCD)提供了一种在后台执行任务的机制,尽管它在结构上与AsyncTask不同.要异步执行某些操作,您只需创建一个队列(如线程),然后传递一个块以dispatch_async()在后台执行.我发现它比AsyncTask更整洁,因为没有涉及子类化; 它或多或少是即插即用的,无论你有什么代码,你想在后台执行.一个例子:

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

其他要点:

1)回调

如果要在后台执行任务并在后台任务完成时更新UI(或在另一个线程上执行某些操作),则可以简单地嵌套调度调用:

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
    });
});
Run Code Online (Sandbox Code Playgroud)

2)全局队列

创建队列时,您还可以使用该dispatch_get_global_queue()函数获取具有特定优先级的全局调度队列(例如DISPATCH_QUEUE_PRIORITY_HIGH).这些队列是普遍可访问的,在您希望将多个任务分配给同一个线程/队列时非常有用.请注意,iOS完全管理内存.

3)记忆

关于内存管理和调度队列有时会有一些混乱,因为它们有自己的dispatch_retain/ dispatch_release函数.但是,请放心,它们被ARC视为Objective-C对象,因此您无需担心调用这些函数.参考rob mayoff关于GCD和ARC 的很好的答案,您可以看到文档描述了GCD队列与Objective-C对象的等价性:

* By default, libSystem objects such as GCD and XPC objects are declared as
* Objective-C types when building with an Objective-C compiler. This allows
* them to participate in ARC, in RR management by the Blocks runtime and in
* leaks checking by the static analyzer, and enables them to be added to Cocoa
* collections.
*
* NOTE: this requires explicit cancellation of dispatch sources and xpc
*       connections whose handler blocks capture the source/connection object,
*       resp. ensuring that such captures do not form retain cycles (e.g. by
*       declaring the source as __weak).
*
* To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
* compiler flags.
*
* This mode requires a platform with the modern Objective-C runtime, the
* Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
* or iOS 6.0 deployment target.
Run Code Online (Sandbox Code Playgroud)

4)多个任务/块

我将补充说,如果任务在多个异步活动完成之前无法继续,GCD有一个分组接口支持同步多个异步块.JörnEyrich和ɲeuroburɳ 在这里提供了对此主题的慷慨解释.如果您需要此功能,我强烈建议您花几分钟时间仔细阅读他们的答案,并了解它们之间的差异.

如果您愿意,文档中有关于该主题的大量信息.

  • 有趣.是否有在主线程上执行的回调? (3认同)

Ign*_*ers 18

iOS中没有类,但您可以使用队列进行模拟.你可以打电话:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Your code to execute in background...
});
Run Code Online (Sandbox Code Playgroud)

对于异步任务和异步代码内部调用下一个队列来在视图中执行某些操作...:

dispatch_async(dispatch_get_main_queue(), ^{
    //Your code to execute on UIthread (main thread)
});
Run Code Online (Sandbox Code Playgroud)

然后,使用这两个队列,您可以创建一个asyncTask类,将此类添加到您的项目中以实现它们:


//
//  AsyncTask.h
//
//  Created by Mansour Boutarbouch Mhaimeur on 25/10/13.
//

#import <Foundation/Foundation.h>

@interface AsyncTask : NSObject

- (void) executeParameters: (NSArray *) params;
- (void) preExecute;
- (NSInteger) doInBackground: (NSArray *) parameters;
- (void) postExecute: (NSInteger) result;
@end
Run Code Online (Sandbox Code Playgroud)
//
//  AsyncTask.m
//
//  Created by Mansour Boutarbouch Mhaimeur on 25/10/13.
//

#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
Run Code Online (Sandbox Code Playgroud)

这是我在项目中使用的示例:


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

@interface SendChatTask : AsyncTask{
    NSArray * chatsNotSent;
}

@end
Run Code Online (Sandbox Code Playgroud)
#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];
    chatsNotSent = [parameters objectAtIndex:0];

    NSString *response;
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    //...
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[ChatJSONParser wrapChatArray: chatsNotSent] options:0 error:&error];
    NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];

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

    response = [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 chatsNotSent) {
            chat.state = STATE_NOT_SENT;
            [chat save];
            AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
            [appDelegate refreshChat];
        }
    } else {

    }
}

@end
Run Code Online (Sandbox Code Playgroud)

以下电话:

[[[SendChatTask alloc] init] executeParameters:[NSArray arrayWithObjects: chatsNotSent, nil]];
Run Code Online (Sandbox Code Playgroud)

您可以添加publishProgress()更新方法和相应的...我暂时不使用它,因为我在后台服务中调用我的异步任务.

我希望它有用.


Jea*_*Luc 5

如果你的目标是早期iOS版本(比用于Grand Central Dispatch的iOS 4),你可以使用NSObject performSelector方法

这是一个例子:

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


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

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

-(void) executeOnMainThread
{
    NSLog(@"executeOnMainThread");
}
Run Code Online (Sandbox Code Playgroud)

  • 不到5%的iOS用户<4.0 (6认同)

归档时间:

查看次数:

30154 次

最近记录:

8 年,3 月 前