programing

파라미터로서의 Objective-C 패스블록

subpage 2023. 4. 24. 23:12
반응형

파라미터로서의 Objective-C 패스블록

어떻게 패스하지?Block에 대해서Function/Method?

나는 노력했다.- (void)someFunc:(__Block)someBlock헛수고로

즉, 어떤 타입이 있습니까?Block?

블록의 유형은 인수와 반환 유형에 따라 달라집니다.일반적인 경우 블록타입은 함수 포인터타입과 같은 방법으로 선언됩니다만,*와 함께^블록을 메서드에 전달하는 방법 중 하나는 다음과 같습니다.

- (void)iterateWidgets:(void (^)(id, int))iteratorBlock;

하지만 보시다시피, 그건 지저분해요.대신 A를 사용할 수 있습니다.typedef블록 유형을 보다 깔끔하게 하려면:

typedef void (^ IteratorBlock)(id, int);

그런 다음 다음과 같은 방법으로 블록을 전달합니다.

- (void)iterateWidgets:(IteratorBlock)iteratorBlock;

이 질문에 대한 가장 쉬운 설명은 다음 템플릿을 따르는 것입니다.

1. 메서드 파라미터로서의 블록

템플릿

- (void)aMethodWithBlock:(returnType (^)(parameters))blockName {
        // your code
}

-(void) saveWithCompletionBlock: (void (^)(NSArray *elements, NSError *error))completionBlock{
        // your code
}

케이스의 기타 용도:

2. 재산으로서의 블록

템플릿

@property (nonatomic, copy) returnType (^blockName)(parameters);

@property (nonatomic,copy)void (^completionBlock)(NSArray *array, NSError *error);

3. 메서드 인수로서의 블록

템플릿

[anObject aMethodWithBlock: ^returnType (parameters) {
    // your code
}];

[self saveWithCompletionBlock:^(NSArray *array, NSError *error) {
    // your code
}];

4. 로컬 변수로서의 블록

템플릿

returnType (^blockName)(parameters) = ^returnType(parameters) {
    // your code
};

void (^completionBlock) (NSArray *array, NSError *error) = ^void(NSArray *array, NSError *error){
    // your code
};

5. 블록(typedef)

템플릿

typedef returnType (^typeName)(parameters);

typeName blockName = ^(parameters) {
    // your code
}

typedef void(^completionBlock)(NSArray *array, NSError *error);

completionBlock didComplete = ^(NSArray *array, NSError *error){
    // your code
};

이것은 도움이 될 수 있습니다.

- (void)someFunc:(void(^)(void))someBlock;

블록을 블록 매개 변수로 전달하면 다음과 같이 수행할 수 있습니다.

//creating a block named "completion" that will take no arguments and will return void
void(^completion)() = ^() {
    NSLog(@"bbb");
};

//creating a block namd "block" that will take a block as argument and will return void
void(^block)(void(^completion)()) = ^(void(^completion)()) {
    NSLog(@"aaa");
    completion();
};

//invoking block "block" with block "completion" as argument
block(completion);

다음 예에서 functions 함수를 사용하여 블록을 통과하는 또 하나의 방법입니다.백그라운드 및 메인 큐에서 어떤 것이든 수행할 수 있는 기능을 만들었습니다.

blocks.h 파일

void performInBackground(void(^block)(void));
void performOnMainQueue(void(^block)(void));

blocks.m 파일

#import "blocks.h"

void performInBackground(void(^block)(void)) {
    if (nil == block) {
        return;
    }

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), block);
}

void performOnMainQueue(void(^block)(void)) {
    if (nil == block) {
        return;
    }

    dispatch_async(dispatch_get_main_queue(), block);
}

필요에 따라 blocks.h를 Import하여 호출합니다.

- (void)loadInBackground {

    performInBackground(^{

        NSLog(@"Loading something in background");
        //loading code

        performOnMainQueue(^{
            //completion hadler code on main queue
        });
    });
}

필요에 따라 블록을 단순 속성으로 설정할 수도 있습니다.

@property (nonatomic, copy) void (^didFinishEditingHandler)(float rating, NSString *reviewString);

블록 속성이 "복사"인지 확인합니다!

물론 typedef도 사용할 수 있습니다.

typedef void (^SimpleBlock)(id);

@property (nonatomic, copy) SimpleBlock someActionHandler;

또한 통상의 c 함수 구문을 사용하여 블록을 호출하거나 호출합니다.

-(void)iterateWidgets:(IteratorBlock)iteratorBlock{

    iteratorBlock(someId, someInt);
}

블록에 대한 자세한 내용은 여기를 참조하십시오.

http://developer.apple.com/library/ios/ # documentation / cocoa / Conceptual / Blocks / Articles / bxGettingStarted . html # //apple_ref / doc / uid / TP40007502 - CH7 - SW 1

나는 항상 블록 구문을 잊어버리는 경향이 있다.차단 선언이 필요할 때 항상 생각나는 부분입니다.누군가에게 도움이 되었으면 좋겠다:)

http://fuckingblocksyntax.com

completeBlock을 작성했습니다.클래스를 흔들면 주사위 값이 반환됩니다.

  1. returnType을 사용하여 typedef를 정의합니다( )..h위에@interface선언)

    typedef void (^CompleteDiceRolling)(NSInteger diceValue);
    
  2. 의 정의@property블록용(.h)

    @property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
    
  3. 메서드를 정의하다finishBlock(.h)

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
    
  4. 이전에 정의된 메서드 삽입 위치.m파일 및 커밋finishBlock로.@property이전에 정의되어 있다

    - (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
        self.completeDiceRolling = finishBlock;
    }
    
  5. 트리거하다completionBlockpass 사전 정의된 변수입력해주세요(다음과 같이 입력해 주세요).completionBlock존재)

    if( self.completeDiceRolling ){
        self.completeDiceRolling(self.dieValue);
    }
    

이 스레드에 대한 답변에도 불구하고 블록을 함수로 사용할 수 있는 함수를 작성하기 위해 정말 애를 먹었습니다.결국, 내가 생각해낸 해결책이 여기 있다.

인 함수로 쓰고 요.loadJSONthreadJSON Web Service 의 URL 을 취득하면, 이 URL 로부터 몇개의 JSON 데이터를 백그라운드스레드에 로드해, 결과의 NSAray* 를 호출 함수로 되돌립니다.

기본적으로 저는 백그라운드 스레드의 복잡성을 일반적인 재사용 가능 기능으로 숨기고 싶었습니다.

이 함수를 다음과 같이 부릅니다.

NSString* WebServiceURL = @"http://www.inorthwind.com/Service1.svc/getAllCustomers";

[JSONHelper loadJSONthread:WebServiceURL onLoadedData:^(NSArray *results) {

    //  Finished loading the JSON data
    NSLog(@"Loaded %lu rows.", (unsigned long)results.count);

    //  Iterate through our array of Company records, and create/update the records in our SQLite database
    for (NSDictionary *oneCompany in results)
    {
        //  Do something with this Company record (eg store it in our SQLite database)
    }

} ];

후를 호출하여 하도록 하는 입니다.이것이 제가 고민했던 부분입니다: 데이터를 선언하는 방법, 데이터가 로드된 후 블록 함수를 호출하여 전달하도록 하는 방법BlockNSArray*:

+(void)loadJSONthread:(NSString*)urlString onLoadedData:(void (^)(NSArray*))onLoadedData
{
    __block NSArray* results = nil;

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{

        // Call an external function to load the JSON data 
        NSDictionary * dictionary = [JSONHelper loadJSONDataFromURL:urlString];
        results = [dictionary objectForKey:@"Results"];

        dispatch_async(dispatch_get_main_queue(), ^{

            // This code gets run on the main thread when the JSON has loaded
            onLoadedData(results);

        });
    });
}

은 함수를위의 하고 StackOverflow는 하지 않았습니다.loadJSONDataFromURL★★★★★★ 。

다만, 이 JSON 로딩 기능의 카피는, 다음의 블로그에서 참조할 수 있습니다.http://mikesknowledgebase.azurewebsites.net/pages/Services/WebServices-Page6.htm

이것이 다른 XCode 개발자들에게 도움이 되기를 바랍니다! (이 질문과 답변이 있다면 잊지 말고 투표해 주세요!)

전체 템플릿은 다음과 같습니다.

- (void) main {
    //Call
    [self someMethodWithSuccessBlock:^{[self successMethod];}
                    withFailureBlock:^(NSError * error) {[self failureMethod:error];}];
}

//Definition
- (void) someMethodWithSuccessBlock:(void (^) (void))successBlock
                   withFailureBlock:(void (^) (NSError*))failureBlock {
    
    //Execute a block
    successBlock();
    failureBlock([[NSError alloc]init]);
}

- (void) successMethod {
}

- (void) failureMethod:(NSError*) error {
}

언급URL : https://stackoverflow.com/questions/7936570/objective-c-pass-block-as-parameter

반응형