2013-02-21 5 views
1

완전하게 형성된 블록 (모든 매개 변수가 포함 된 블록)을 메서드에 전달하여 메서드에서 해당 블록을 실행할 수 있습니까?블록을 매개 변수로 전달

- (void) reportSuccessWithBlock:(GenericBlockType)block{ 
     if (block) 
     { 
      if (self.returnOnMainThread) 
      { 
       dispatch_async(dispatch_get_main_queue(),^
           { 
            block; 
           }); 
      } 
      else 
      { 
       block; 
      } 
     } 

} 

:

if (//block exists) 
     { 
      if (self.returnOnMainThread) 
      { 
       dispatch_async(dispatch_get_main_queue(),^
           { 
            //call block here 
           }); 
      } 
      else 
      { 
       //call block here 
      } 
     } 

그러나 이상적으로 내가 밖으로 방법과 유사한 방법으로 추상적에 위의 코드 아마도 나머지 미사일을하고 싶습니다 :이 구조 내 프로젝트에서 반복 한 순간

편집 :

블록 유형을 미리 알 수 없습니다.

  1. 방법은 일반적인 블록을 받아 들일 수 :

    그래서 호출 경로는 (가능 내가 모르는) 위의 코드에서 몇 가지 가정이 있습니다이

    - (void) someMethod:(void (^)(NSArray *array))success 
    { 
    //Some code here setting up the array to be passed back 
    
        [self reportSuccessWithBlock:success(array)]; 
    
    } 
    

    처럼 보일 수 있습니다 유형 블록이 모든 파라미터 존재로 전달 실제로

+1

는 블록이 매개 변수의 다른 수를 수용 할 뜻, "블록 자체가 다른 변수의 숫자를 포함 할 수 있습니다"? – trojanfoe

+0

@trojanfoe 내 말은이 방법은 다른 서명을 가진 블록을 받아 들일 수 있어야한다는 것입니다. (void (^) (NSArray * array)) success 또는 (void (^) (NSDictionary * dictionary, NSUInteger value)) 성공 – williamb

+0

블록에 매개 변수를 제공해야하고 그렇지 않은 경우 문제가 될 수 있습니다. 그들이 무엇이 될 것인지를 안다면, 어떻게 할 수 있습니까? 그것은 가능할 수도 있지만 지저분 할 것이고 노력의 가치가있는 것처럼 들리지는 않습니다. – trojanfoe

답변

2
를 실행하지 않고 수
  • 의견에서 말했던 것처럼 두 개의 다른 블록이있는 경우 두 블록을 다음과 같이 병합 할 수 있습니다. 그러나 이것은 상당히 해킹 된 것이므로 블록을 호출 할 때 object의 클래스를 확인해야합니다. 나는 NSArray 매개 변수를 사용하는 아이디어를 생각

    - (void) someMethod { 
    
        [self reportSuccessWithBlock:^(id object, NSUInteger value) { 
    
         if ([object isKindOfClass:[NSArray class]]) { 
    
          // returned an NSArray and `value` is 0 (unset) 
    
         } 
    
         else if ([object isKindOfClass:[NSDictionary class]]) { 
    
          // returned an NSDictionary and the `value` is not 0 (unset) 
    
         } 
    
         else { 
    
          // something has gone wrong somewhere! 
    
         } 
    
        }]; 
    
    } 
    
    1

    OK : 블록이 호출 될 때 따라서

    - (void) reportSuccessWithBlock:(void (^) (id object, NSUInteger value)) block { 
    
        if (!block) 
         return; 
    
        if (self.returnOnMainThread) { 
         dispatch_async(dispatch_get_main_queue(), block((id)someObject, value)); // return 0 instead if there is no value 
        } 
    
        else { 
         block((id) someObject, value)); // return 0 instead if there is no value 
        } 
    } 
    

    는, 당신이 할 필요가있는 모든 클래스를 확인하고 반환 된 객체와 무엇이든 할 것입니다

    typedef void ^(MYBLOCK)(NSArray *args); 
    

    과 같은 방법을 구현 :

    을 당신이 당신의 블록에 동일한 서명을 줄 수 있도록 작동합니다
    - (void)reportSuccessWithBlock:(GenericBlockType)block 
            andArguments:(NSArray *)args 
    { 
        if (block != nil) 
        { 
         if (self.returnOnMainThread) 
         { 
          dispatch_async(dispatch_get_main_queue(), ^{ 
           block(args); 
          }); 
         } 
         else 
         { 
          block(args); 
         } 
        } 
    } 
    

    그리고 적절한 유형의 인수가 올바른 순서로 블록에 주어지는 경우입니다 (사소한 소리는 들리지만이 문제가 발생하면 모든 종류의 애그로가 발생합니다).

    MYBLOCK block1 = ^(NSArray *args) { 
        // I accept NSNumber, NSString, NSValue 
        NSAssert(args.count == 3, @"Invalid argument count"); 
        NSNumber *arg1 = args[0]; 
        NSString *arg2 = args[1]; 
        NSValue *arg3 = args[2]; 
    
        // Do my thing 
    }; 
    

    하고 싶은 전화 :

    [someClass reportSuccessWithBlock:block1 
            andArguments:@[ @(1), @"Hello", @(cgpoint) ]]; 
    
    +0

    당신의 대답은 적어도 나를 위해 매우 유용합니다 - 방법의 매개 변수로서 사용법 블록에 관한 10 개의 기사를 읽고 여전히 질문을 가지고 있습니다 - 당신의 대답을 읽고 완전히 이해하십시오. 감사합니다. 특히 다음 줄에 대해 감사합니다.'[someClass reportSuccessWithBlock : block1 andArguments : @ [@ (1), @ "Hello", @ (cgpoint)]]' – gbk