2013-02-08 3 views
2

내 코드에서 여러 번 호출 할 수있는 ErrorBlock (errorBlock)을 정의했습니다. 나는 한 번만 호출에 대해 알리고 싶지만, 내 생각은 내 ErrorBlock (errorBlock)을 다른 (pErrorBlock) 안에 랩핑하고 그 하나를 설정하지 않는 것입니다.Obj-C 블록을 매개 변수로 사용

이제 innerBlock에 대한 참조를 nil로 설정하는 정리 메소드가 필요합니다. 하지만 내부 블록을 정리 메서드 (Test 1)로 넘겨 주면 내부 ErrorBlock nil self (Test 2)를 설정할 때 다른 결과가 나타납니다.

테스트 1의 코드 (약간 수정 됨)를 사용하여 테스트 2의 결과를 어떻게 얻을 수 있습니까?

-(void)testBlocks{ 
    __block ErrorBlock pErrorBlock= ^(void){ 
     NSLog(@"Foo"); 
    }; 
    NSLog(@"test: %p",pErrorBlock); 

    ErrorBlock errorBlock = ^(void){ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      if(pErrorBlock){ 
       NSLog(@"call: %p",pErrorBlock); 
       pErrorBlock(); 
      } 

      [self cleanupErrorBlockWith:pErrorBlock]; 
     }); 
    }; 

    errorBlock(); 
    errorBlock(); 
} 

- (void) cleanupErrorBlockWith:(ErrorBlock)errorBlock{ 

    NSLog(@"cleanup: %p",errorBlock); 
    errorBlock = nil; 
    NSLog(@"after cleanup: %p",errorBlock); 
} 

결과는 : 원하는 결과 내 두 번째 테스트,

2013-02-08 16:39:04.484 Tests[9501:907] test: 0x3a6ba8 
2013-02-08 16:39:04.496 Tests[9501:907] call: 0x3a6ba8 
2013-02-08 16:39:04.497 Tests[9501:907] Foo 
2013-02-08 16:39:04.498 Tests[9501:907] cleanup: 0x3a6ba8 
2013-02-08 16:39:04.499 Tests[9501:907] after cleanup: 0x0 
2013-02-08 16:39:04.500 Tests[9501:907] call: 0x3a6ba8 
2013-02-08 16:39:04.501 Tests[9501:907] Foo 
2013-02-08 16:39:04.502 Tests[9501:907] cleanup: 0x3a6ba8 
2013-02-08 16:39:04.503 Tests[9501:907] after cleanup: 0x0 

입니다

:

-(void)testBlocks{ 
    __block ErrorBlock pErrorBlock= ^(void){ 
     NSLog(@"Foo"); 
    }; 
    NSLog(@"test: %p",pErrorBlock); 

    ErrorBlock errorBlock = ^(void){ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      if(pErrorBlock){ 
       NSLog(@"call: %p",pErrorBlock); 
       pErrorBlock(); 
       NSLog(@"cleanup: %p",pErrorBlock); 
       pErrorBlock = nil; 
       NSLog(@"after cleanup: %p",pErrorBlock); 
      } 
     }); 
    }; 

    errorBlock(); 
    errorBlock(); 
} 

내 프리스트 테스트, 내가 이해하지 못하는 결과를 신발 결과 :

2013-02-08 16:42:18.485 Tests[9540:907] test: 0x3a6ba8 
2013-02-08 16:42:18.496 Tests[9540:907] call: 0x3a6ba8 
2013-02-08 16:42:18.498 Tests[9540:907] Foo 
2013-02-08 16:42:18.499 Tests[9540:907] cleanup: 0x3a6ba8 
2013-02-08 16:42:18.500 Tests[9540:907] after cleanup: 0x0 
+1

분명히 'errorBlock = nil;'은 매개 변수로 전달되면 아무런 효과가 없습니다. – trojanfoe

답변

2

값을 기준으로 블록을 전달하고 있습니다. 이와 같이 참조로 전달하십시오. 또한 이동 cleanupErrorBlockWith:if 성명을 호출.

-(void)testBlocks{ 
    __block ErrorBlock pErrorBlock= ^(void){ 
     NSLog(@"Foo"); 
    }; 
    NSLog(@"test: %p",pErrorBlock); 

    ErrorBlock errorBlock = ^(void){ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      if(pErrorBlock){ 
       NSLog(@"call: %p",pErrorBlock); 
       pErrorBlock(); 
       [self cleanupErrorBlockWith:&pErrorBlock]; 
      } 
     }); 
    }; 

    errorBlock(); 
    errorBlock(); 
} 


- (void) cleanupErrorBlockWith:(ErrorBlock*)errorBlock{ 
    NSLog(@"cleanup: %p",*errorBlock); 
    *errorBlock = nil; 
    NSLog(@"after cleanup: %p",*errorBlock); 
} 
+0

감사합니다! 방금 같은 테스트 케이스를 썼다. – Jakob

+0

오케이 .. 만약 당신이'ErrorBlock'에 대한 정의를 주었다면 5 분 전에 질문에 대답했을 것입니다. : D 어쨌든 +1 당신의 질문에 대한 블록 변수를 내 개념을 지우기 : –

+0

nil 호출은 허용되어야합니다. 그게 내가 왜 오히려 그것을 밖으로 가지고 싶어. 그 이유는 나의 실제 정리 방법이 여러 블록 인수를 취하고 그 모두에 대해 nil을 테스트하고 싶지 않기 때문입니다. – Jakob