当前位置: 首页 > 知识库问答 >
问题:

iOS/Objective-C相当于Android的AsyncTask

养聪
2023-03-14

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

共有3个答案

乌翔
2023-03-14

如果您的目标早于iOS版本(大中央调度iOS4),您可以使用NSObject performSelector方法

>

  • 在后台线程上执行performSelectorInbackground: with Object:

    并在主线程上执行performSelectorOnMainThread:withObject:waitUntilDone:

    这是一个例子:

    [self performSelectorInBackground:@selector(executeInBackground) withObject:nil];
    
    
    -(void) executeInBackground
    {
        NSLog(@"executeInBackground");
    
        [self performSelectorOnMainThread:@selector(executeOnMainThread) withObject:nil waitUntilDone:NO];
    }
    
    -(void) executeOnMainThread
    {
        NSLog(@"executeOnMainThread");
    }
    

  • 龙兴学
    2023-03-14

    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]];
    

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

    我希望这有帮助。

    欧阳洲
    2023-03-14

    Grand Central Dispatch(GCD)提供了一种在后台执行任务的机制,尽管其工作方式在结构上与AsyncTask不同。要异步执行某些操作,只需创建一个队列(如线程),然后将一个块传递给要在后台执行的dispatch\u async()。我发现它比AsyncTask更简洁,因为不涉及子类;它或多或少是即插即用的,只要你有代码想在后台执行。例如:

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

    如果要在后台执行任务,并在后台任务完成时更新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
        });
    });
    

    创建队列时,您还可以使用dispatch\u get\u global\u queue()函数获取具有特定优先级的全局调度队列(例如dispatch\u queue\u priority\u HIGH)。这些队列是普遍可访问的,当您想要将多个任务分配给同一个线程/队列时,它们非常有用。请注意,内存完全由iOS管理。

    内存管理和调度队列有时会出现一些混淆,因为它们有自己的功能。但是,请放心,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.
    

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

    如果你有这样的倾向,留档有大量关于这个主题的信息。

     类似资料:
    • 问题内容: 在iOS应用中,我使用了 获取正在webView上显示的图像的src目录。我想对Android执行相同操作。我有什么选择? 基本上,目的是捕获路径,以便我可以通过电子邮件发送此图片… 即。 这样,当用户单击链接或将其发布到facebook等时,将加载相同的图像。 问题答案: 是的,我在Android中非常想念这种方法;) 要执行JavaScript并获得响应,您可以执行以下操作: 在代

    • 如需集成DeepShare,请参考DeepShare iOS集成 1. 导入SDK 你可以用下面的方法进行导入: 方法1. 使用CocoaPods导入 若未安装CocoaPod,请先在终端执行 gem install cocoapods来安装CocoaPod 创建Podfile文件。若目录下没有Podfile文件,请在项目目录下执行pod init,若已有,请直接执行下一步 打开Podfile文件

    • 问题内容: Java相当于Cocoa委托的代表? (我知道我可以将一个接口传递给一个类,并让该类调用适当的方法,但是我想知道是否还有其他方法可以实现更接近于Cocoa / Objective- C的非正式协议的东西) 问题答案: 简短的答案是,Java中没有什么比您想的要近的了,但还有其他选择。委托模式并不难实现,只是不像使用Objective-C那样方便。 “非正式协议”在Objective-C

    • 问题内容: 我正在寻找Java ByteBuffer的“ C ++”。 我可能会丢失明显的内容,或者仅需要一个孤立的用法示例进行澄清。我浏览了iostream家族,它似乎可以提供基础。具体来说,我希望能够: 从字节数组/点构建缓冲区,并从缓冲区获取原语,例如getByte,getInt 使用原语(例如putByte,putInt)构建缓冲区,然后获取字节数组/指针。 问题答案: 您已经拥有,或者可

    • 问题内容: Java是否具有表示一段时间的数据类型,例如34秒,5分钟等。 我已经看到了一些TimeSpan的实现,这些实现涵盖了从12月10日到12月11日这样的时间段。 我需要的是类似C#中的TimeSpan。 问题答案: 目前还不是JDK的一部分,但是将被合并到JDK 7中-尝试Joda Time

    • 问题内容: 从Java世界进入C#,是否有等效的HashMap?如果没有,您会推荐什么? 问题答案: 可能是最接近的。实现接口(类似于Java的接口)。 您应该注意一些明显的区别: 添加/获取项目 Java的HashMap具有用于设置/获取项目的和方法 C#的词典使用索引来设置/获取项目 键 Java 允许空键 如果您尝试添加空键,.NET会引发 添加重复密钥 Java 将用新值替换现有值。 如果