我熟悉在 Android 中使用 AsyncTask
:创建一个子类,调用 execute
在子类的实例上调用 —dc79735d406f552ca747f6bf-8b- onPostExecute
线。 iOS中的等价物是什么?
原文由 SundayMonday 发布,翻译遵循 CC BY-SA 4.0 许可协议
我熟悉在 Android 中使用 AsyncTask
:创建一个子类,调用 execute
在子类的实例上调用 —dc79735d406f552ca747f6bf-8b- onPostExecute
线。 iOS中的等价物是什么?
原文由 SundayMonday 发布,翻译遵循 CC BY-SA 4.0 许可协议
iOS 中没有相应的类,但您可以使用队列模拟它。您可以致电:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Your code to execute in background...
});
对于异步任务和你的异步代码调用下一个队列在视图中做一些事情……:
dispatch_async(dispatch_get_main_queue(), ^{
//Your code to execute on UIthread (main thread)
});
然后,使用这两个队列,您可以创建一个 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
//
// 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
这是我在项目中使用的示例:
#import "AsyncTask.h"
#import "Chat.h"
@interface SendChatTask : AsyncTask{
NSArray * chatsNotSent;
}
@end
#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
以及以下调用:
[[[SendChatTask alloc] init] executeParameters:[NSArray arrayWithObjects: chatsNotSent, nil]];
您可以添加一个 publishProgress()
更新方法和相应的…我暂时不使用它,因为我在后台服务中调用我的异步任务。
希望对您有所帮助。
原文由 IgniteCoders 发布,翻译遵循 CC BY-SA 3.0 许可协议
3 回答996 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
1 回答859 阅读✓ 已解决
2 回答973 阅读
2 回答909 阅读
1 回答868 阅读
2 回答789 阅读
原问题的答案:
Grand Central Dispatch (GCD) 提供了一种在后台执行任务的机制,尽管它的工作方式在结构上与 AsyncTask 不同。要异步执行某些操作,您只需创建一个队列(如线程),然后将一个块传递给
dispatch_async()
以在后台执行。我发现它比 AsyncTask 更整洁,因为不涉及子类化;它或多或少是即插即用的,只要您有要在后台执行的代码。一个例子:其他要点:
1)回调
如果你想在后台执行一个任务并在后台任务完成时更新 UI(或在另一个线程上做一些事情),你可以简单地嵌套调度调用:
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 对象的等效性:4)多个任务/块
我要补充一点,如果一个任务在多个异步活动完成之前无法继续,那么 GCD 有一个分组接口支持同步多个异步块。 Jörn Eyrich 和 ɲeuroburɳ 在这里 对这个主题进行了详尽的解释。如果您需要此功能,我强烈建议您花几分钟时间仔细阅读他们的两个答案并理解它们之间的区别。
如果您愿意,该 文档 包含有关该主题的大量信息。