2017-03-07 5 views
3

변수로 블록을 선언하는 것이 가장 좋습니다.Objective-C 블록을 변수로 선언하는 모범 사례

id actionHandler = ^(UIAlertAction * action) { 
    // Handling code 
}; 

이상과 같이 사용할 수 :

처음에 나는이 같은 내 블록 변수가 쓴

UIAlertAction *action = [UIAlertAction actionWithTitle:@"Title" 
               style:UIAlertActionStyleDefault 
               handler:actionHandler]; 

을하지만 Apple's Working With Blocks 가이드를 가로 질러 왔을 때, 나는 내가 지금처럼 다시 쓸 수 보았다 :

void (^actionHandler)(UIAlertAction * action) = ^(UIAlertAction * action) { 
    // Handling code 
}; 

신고하는 데 올바른 방법입니까? 그것은 제 생각으로는 읽을 수있는 것이 아니지만 Objective-C에 대한 많은 경험이 없습니다. 블록을 변수로 선언하는 것이 가장 좋은 방법은 무엇입니까?


편집 : 좋아, 덕분에 모든 해명! typedefshown으로 정의하면 입니다. amin-negm-awad 등은 좋은 대체 접근 방법입니다.

+1

를 사용합니다. 예를 들어 http://stackoverflow.com/questions/8956921/setting-up-a-block-property-in-custom-class/8956967#8956967 –

답변

2

아무도 만능 여기에 대답하지 있습니다 :

id myHandler = ^(NSString *str) { 
    NSLog(@"%@", str); 
}; 
// Error: Called object type id is not a function or function pointer 
myHandler(@"Hello"); 

을 : 당신이 id로 블록 변수를 선언 할 때 더 이상 그래서 수동으로 문제가된다 호출시 컴파일 정보를 귀하의 블록과 연관이 없다 코드에서 블록을 직접 호출하려면 블록으로 다시 캐스팅해야합니다.

반면 블록 변수를 매개 변수로 사용하는 함수에 전달할 수 있도록 블록 변수 만 선언하면 id을 사용하면보다 쉽게 ​​읽을 수 있습니다. 나는 수사학의 질문을 할 dasblinkenlicht에 의해 언급 된 문제에 대한 추가

3

:

당신이 ... 당신이 코드를 대체 할 수 있다는 사실을 알고 가능성 :

NSString *string = @"All about types"; 

을 ...이 코드 :

id string = @"All about types"; 

하시겠습니까? 나는 확신한다.

왜 var의 "입력 된"버전을 id 버전으로 변경해야합니까? 유일한 이유는 블록 유형의 구문이 읽기 쉽지 않고 읽기 쉽지 않기 때문입니다. 다음

typedef void (^ActionHandlerType)(UIAlertAction * action); 

: 그리고 난 항상 손재주 구문을 제거하는 구체적인 유형을 정의

ActionHandlerType actionHandler = ^(UIAlertAction * action) { 
    // Handling code 
}; 

만들 것을 분명히 : id는 목표 - C의 메시지 전달의 동적 특성을 사용하는 중대하다 . 그러나 블록 실행은 늦은 바운드가 아닙니다. 블록의 매개 변수도 숫자 나 유형을 변경할 수 없기 때문에 동적으로 바인딩 할 수있는 것이 없습니다. 고정 된 숫자의 인수, 고정 유형의 간단한 호출입니다.따라서 id의 사용은 블록의 객체 특성의 부작용으로 가능합니다. 그러나 의도 된 사용법은 아닙니다.

BTW : 매개 변수 목록에 구체적인 유형을 사용하는 경우 Xcode에서 인수 구문을 자동 완성 할 수 있습니다. id으로는 불가능합니다. 명백하게.

1

이 컨텍스트에서 id을 사용하는 경우 컴파일러는 선언 한 블록 유형이 메서드가 예상하는 블록 유형과 일치하는지 확인하지 않습니다. 실수로 블록을 잘못 잡아서 디버깅하기가 어렵다면 메소드가 블록을 사용하려고 할 때 일이 발생할 것입니다 ...

따라서 실수하지 않으시면 id을 입력하십시오. 올바른 타입이므로 컴파일러가 당신을 도와 줄 수 있습니다.

는 쉽게 만들려면, 결과적으로 더 적은 오류가 발생하기 쉬운 타입 정의, 예컨대 : 당신은 또한`typedef` 사용을 고려할 수

typedef void (^AlertActionHandler)(UIAlertAction * action); 
... 

AlertActionHandler actionHandler = ^(UIAlertAction * action) { ...