programing tip

Android의 AsyncTask에 해당하는 iOS / Objective-C

itbloger 2020. 11. 8. 09:31
반응형

Android의 AsyncTask에 해당하는 iOS / Objective-C


저는 AsyncTaskAndroid에서 사용 하는 데 익숙 합니다. 하위 클래스를 만들고 하위 클래스 execute의 인스턴스를 onPostExecute호출하고 UI 스레드 또는 주 스레드에서 호출됩니다. iOS에서 동등한 것은 무엇입니까?


원래 질문에 대한 답변 :

GCD (Grand Central Dispatch)는 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
});

기타 포인트 :

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
    });
});

2) 글로벌 대기열

대기열을 생성 할 때 dispatch_get_global_queue()함수를 사용하여 특정 우선 순위 (예 :)의 전역 디스패치 대기열을 가져올 수도 있습니다 DISPATCH_QUEUE_PRIORITY_HIGH. 이러한 대기열은 보편적으로 액세스 할 수 있으며 동일한 스레드 / 큐에 여러 작업을 할당하려는 경우에 유용합니다. 메모리는 iOS에서 완전히 관리됩니다.

3) 메모리

메모리 관리 및 디스패치 큐에 자체 dispatch_retain/ dispatch_release기능 이 있기 때문에 때때로 혼란이 있습니다. 그러나 ARC에서 Objective-C 객체로 취급하므로 이러한 함수 호출에 대해 걱정할 필요가 없습니다. 참조 강탈 mayoff의 위대한 대답 GCD와 ARC에 대한을, 당신은 문서 객체를 목표 - C와 GCD 큐 '등가를 설명 볼 수 있습니다 :

* 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.

4) 여러 작업 / 블록

GCD에는 여러 비동기 활동이 완료 될 때까지 작업을 계속할 수없는 경우 여러 비동기 블록 동기화를 지원하는 그룹화 인터페이스가 있습니다. Jörn Eyrich와 ɲeuroburɳ는 여기 에서이 주제에 대한 관대 한 설명을 제공합니다 . 이 기능이 필요한 경우 몇 분 동안 두 답변을 자세히 읽고 차이점을 이해하는 것이 좋습니다.

문서는 당신이 그렇게 경사하는 경우에는 주제에 대한 풍부한 정보를 가지고 있습니다.


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()업데이트 방법과 각각을 추가 할 수 있습니다 . 백그라운드 서비스에서 비동기 작업을 호출하기 때문에 지금은 사용하지 않습니다.

도움이 되었기를 바랍니다.


이전 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");
}

스위프트 3

In Android when I wanted to run a task on a background thread and then update the UI when it finished, I used AsyncTask (example). Now when I am making iOS versions of my apps, I use Grand Central Dispatch (GCD) to do the same thing. Here is how it is done with Swift:

DispatchQueue.global(qos: .background).async {

    // code to be run on a background task

    DispatchQueue.main.async {

        // code to be run on the main thread after the background task is finished
    }
}

Notes

참고URL : https://stackoverflow.com/questions/11728098/ios-objective-c-equivalent-of-androids-asynctask

반응형