2009-05-06 4 views
0

원격 서버에서 대리인의 입력이 필요할 때 호출되는 대리자 메서드를 디자인하고 있습니다. 그 시점의 델리게이트는 서버에 전송할 데이터를 채우고 그 시점에서 오류가 있는지 서버에 알리는 역할을 담당합니다.대리자 메서드에서 NSError 개체를 반환해야합니까?

내가 지금 가지고있는 위임 방법은 다음과 같습니다.이 시점에서

-(void)server:(MBServer*)server 
willSendData:(NSMutableString*)data 
     error:(NSError**)error; 

이 대리자에 전달되는 인 NSMutableString을 수정하여 전송하는 서버에 대한 데이터를 제공 할 수 있습니다 또한, 그것은 NSError를 만들 수 있습니다 새 NSError 인스턴스에 error 변수를 설정하여 되돌릴 수 있습니다.

이 문제는 대리자 메서드가 NSInvocation을 통해 다른 스레드에서 호출 될 수 있다는 점입니다. 대리자는 새 NSError 개체를 만들 수 있지만 다른 스레드가 응답을 받기 전에 현재 스레드에서 자동 렌더링됩니다.

단일 스레드 응용 프로그램에서는 위임자가 즉시 응답을 유지할 수 있기 때문에 문제가되지 않지만 다중 스레드 설계에서는이를 수행 할 수 없기 때문에 (다시 말하면 현재 이벤트 루프는 자동으로 해제되므로 그것). 델리게이트가 그것을 릴리즈 할 수 있도록 델리게이트는 에러를 유지해야한다.

이것은 공개 API 용이며 개발자가 오류 객체를 유지해야한다는 것을 문서를 통해 요구하는 아이디어를 좋아하지 않습니다. 너무 안전하지 않은 것 같습니다. 나는 생각했다

// You *must* retain the returned error before 
// passing it back or you will crash 

-(void)server:(MBServer*)server 
willSendData:(NSMutableString*)data 
     error:(NSError**)error; 

다른 아이디어를 반환 값으로 NSError를 보낼 수 있었다 (대부분의 방법은 부울을 반환하고 NSError 이중 포인터를 걸릴 다소 표준이 아닌 것 같다). 그것은 또한 이상하게 보입니다.

-(NSError *)server:(MBServer*)server 
     willSendData:(NSMutableString*)data; 

나는 또한 변경 가능한 사전을 전달하고 대리인에게 오류를 채우라고 요청했습니다. 그런 다음 사전은 오류를 보존하여 안전하게 스레드간에 다시 가져옵니다.

// Send your NSError response in the dictionary with the key 
// MBServerErrorResponseKey 

-(void)server:(MBServer*)server 
willSendData:(NSMutableString*)data 
    response:(NSMutableDictionary*)response; 

누구나이 디자인 문제를 처리 했습니까? 그렇다면 해결책은 무엇입니까?

감사합니다. 당신이 할 수

답변

3

어때? : 위임 메서드를 직접 호출하는 대신 NSInvocation을 통해 "트램펄린"메서드를 호출하십시오. 트램 폴린 (구현할 것임)은 델리게이트 메소드를 호출하고 반환하기 전에 오류를 유지합니다. 다른 방법 : trampoline (서버 객체의 메소드 일 수 있음)은 전달 된 인수를 사용하여 대리자에게 호출을 래핑 한 다음 오류를 유지하고 반환합니다.

+0

좋은 생각입니다. 그리고 그게 내가 NSString을 사용할 수있게하고 변경할 수있는 것이 아니라. 그래서 내가 만들 것 : @implementation MBServer을 - (무효) MB_threadSafeServerWillSendData : (있는 NSString **) 문자열 오류 : (NSError **) { [위임 서버 : 자기 willSendData : 문자열 오류 : 오류] ; [* 문자열 유지]; [* 오류 유지]; } @end 을 별도의 스레드에서 호출 하시겠습니까? –

+0

그래, 나에게 맞는 것 같아. NSString (또는 심지어 NSData) 비록 메서드를 반환하는 경우 그것은 명확한 수도 있지만 생각합니다. –

+0

사실, 한 가지 더 : 트램 폴린에 대리인을 전달하고 싶을 것입니다. 그렇지 않으면 요청 호출과 호출 사이에서 변경되면 이상한 동작이 발생합니다. (심지어 트램폴린의 실행 중 변경되면 더 이상한!) 아마도 : - (NSData *) MB_threadSafeDataToSendToDelegate : (id) localDelegate 오류 : (NSError **) {* error = nil; NSData * data = [localDelegate dataToSendForServer : 자체 오류 : 오류]; [* 오류 유지]; 데이터를 반환; } –

0

한가지는 서버가 무엇을 실제로 얻을 수있는 getLastErrorForServer: 메서드를 호출 할 수있는 무언가가 stopFlag과를 설정하여 잘못된 서버를 알리기 위해 위임을 허용 할

-(void)server:(MBServer*)server 
willSendData:(NSMutableString*)data 
     shouldStop:(BOOL*)stopFlag; 
-(NSError*)getLastErrorForServer:(MBServer*)server; 

이 같은 시도이다 잘못됐다. server:WillSendData: 메서드가 포인터를 전달하는 대신 BOOL을 반환하는 것이 더 적합 할 수도 있습니다.

관련 문제