2014-12-04 3 views
0

내가 하위 계층 API 세트를 가지고 객체 :objc 가변의 주요 유형 인수 및

- (NSDictionary*) startRecord; 
- (NSDictionary*) stopRecord; 
- (NSDictionary*) switchMicrophone; 
- (NSDictionary*) enableAutoRecord:(BOOL)enable; 
- (NSDictionary*) deleteFile:(NSString*)filename; 
- (NSDictionary*) enableDatetimeStampOverlay:(BOOL)enable; 
- (NSDictionary*) setVideoResolution:(RESOLUTION_PARA)param; 
- (NSDictionary*) setExposureValue:(EXPOSURE_VALUE_PARA)param; 
- (NSDictionary*) setVolume:(VOLUME_PARA)param; 
- (NSDictionary*) setWifiConfigWithSsid:(NSString*)ssid AndPassword:(NSString*)password; 
- (NSDictionary*) formatSDCard; 
// ... the # of parameters are at most 3 

나는, 하위 계층 API를 포장 중 하나를 상위 계층 API를 만들고 싶습니다 그것은 다음과 같다 : 상위 계층

- (void) enableAutoRecord:(BOOL)isEnable 
{ 
    ... 
    dispatch_async(self.mySerialQueue, ^{ 
     ... 
     NSDictionary *response = [self.lowerLayer enableAutoRecord:isEnable]; 
     ... 
    }); 
} 

, 나는 많은 복사본 & 페이스트가 있음을 발견했다.

- (void) enableAutoRecord:(BOOL)isEnable 
{ 
    [self wrap_lower_layer_command:@"enableAutoRecord:", isEnable]; 
} 

"wrap_lower_layer_command"작성 방법은 다음과 같습니다. 나는 nsinvocation, objc_sendMsg 및 가변 인수를 연구했습니다. 하지만 타입 문제에 붙어 있습니다. 예를 들면 다음과 같습니다.

T arg = p1; 
[invocation setArgument:&arg atIndex:2]; 

p1 유형이 무엇인지 알 수 없습니다. 아마도 id, BOOL, int 또는 다른 것일 수 있습니다. 더 높은 계층의 API에 & 붙여 넣기 코드를 리팩토링하는 더 좋은 방법이 있습니까? 힌트를 보내 주시면 감사하겠습니다.

답변

2

Message Forwarding을 조사해야합니다.

- (void)forwardInvocation:(NSInvocation *)anInvocation 
{ 
    if ([self.lowerLayer respondsToSelector:[anInvocation selector]]) { 
     [anInvocation retainArguments]; // Thanks newacct 
     dispatch_async(self.mySerialQueue, ^{ 
      … 
      [anInvocation invokeWithTarget:self.lowerLayer]; 

      void *returnValue; 
      [invocation getReturnValue:&returnValue]; 
      NSDictionary *response = (__bridge NSDictionary *)returnValue; 
      … 
     }); 
    } else { 
     [super forwardInvocation:anInvocation]; 
    } 
} 

나는 반환 값에 대한 부분을 포함하는 것을 잊었다.


-retainArguments이 추가되었습니다.

+0

'[anInvocation retainArguments];는 비동기 적으로 사용되므로 잊지 마세요. 또한'-methodSignatureForSelector :'를 구현하는 것이 필요하지만, 꽤 명료해야한다. – newacct

+0

@newacct 도움을 주셔서 감사합니다! –

+0

감사! 상위 - 레이어 API를 약간 chanaged하면 : - (void) enableAutoRecord : (BOOL) isEnable withCompleteHandler : (CompleteHandler) completeHandler'. 어떻게 [anInvocation invokeWithTarget : self.lowerLayer];와'[self.lowerLayer respondsToSelector : [anInvocation selector]]가 유효하도록 anInvocation에서 arg completeHandler를 제거 할 수 있습니까? – Arton