2009-08-03 5 views
11

나는 다음과 같은 코드가 있습니다목표 - C# import를 루프

#import <Foundation/Foundation.h> 
#import "ServerRequest.h" // works even though this line is included 
#import "ServerResponseRecord.h" 

@protocol ServerRequestDelegate<NSObject> 

-(void)request:(id)request gotResponseRecord:(ServerResponseRecord*)response; 
-(void)request:(id)request gotError:(NSError*)error; 

@end 

그것은 컴파일하고 잘 실행합니다. 내가 가진 메소드 선언을 대체 할 경우, :

-(void)request:(ServerRequest*)request gotResponseRecord:(ServerResponseRecord*)response; 
-(void)request:(ServerRequest*)request gotError:(NSError*)error; 

나는 예상치 못한 구문 오류 "예상 ')' 'ServerRequest에'전에 오류"를 얻을. 내가 이것이 문제가 될 수 있다고 생각할 수있는 유일한 이유는 ServerRequestDelegate.h와 ServerRequest.h # 서로를 가져 오는 것입니다. 그러나, 왜 코드가 (id) 요청으로 #import 행과 함께 작동하는지 이해할 수 없습니다. 또한 왜 구문 오류인지 이해하지 못합니다.

누군가 좋은 설명을 해줄 수 있습니까?

+1

http://stackoverflow.com/questions/10019961/objective-c-class-directive-before-interface에는 가져 오기 루프에 대한 명시적인 예와 '@ 클래스'를 사용하여 피하는 방법이 있습니다. – bbum

답변

24

당신은 이미 설명을 암시했습니다 : # 수입주기.

@class ServerRequest; 

이것은 앞으로 클래스 선언이며, 수입 루프를 중단 할 수 있습니다 : 내가 할 것

우선은 #include를 제거하고 @protocol 정의 위에 다음 줄을 추가합니다. 자세한 내용은 this SO question을 확인하십시오. 애플은 또한 this guide에 간략한 설명을하고있다.

기본적으로, #import '는 파일을 보내고하는 것은 문제의 파일에 해당 파일의 전체 텍스트를 가져올 수 컴파일러가, 그리고 #import#include보다 "똑똑"하지만, 당신이 가져 오기 오류에서 면역있어 의미하지 않는다 . @class 선언은 헤더를 가져 오지 않고 클래스가 존재 함을 컴파일러에 알리는 방법입니다. 클래스 이름에 대해서만 알 필요는 있지만 사용하는 메소드는 신경 쓰지 않는 경우에 사용하는 것이 적절합니다. 일반적으로 .h 파일에서 @class을 사용하고 실제로 클래스와 상호 작용하는 .m 파일에서 #import을 사용하려고합니다.

+0

예, 헤더에있는 @class로 이동하면 레벨 수에 관계없이 더 나은 것으로 선언됩니다. 그러나 문제가 적절한 순방향 선언이없는 순환 종속성이 아니라면 헤더에 잠복 버그가있을 수 있습니다. –

+1

사실입니다.하지만'id'를 타입으로 사용하면 헤더가 포함되어 작동하지만'ServerRequest * '로 정적으로 타이핑하면 헤더가 괜찮을 것입니다. 컴파일러는 'ServerRequest' 클래스에 관한 정보를 찾아 내기 시작할 때 문제가됩니다. –

0

#import "루프"는 문제가되지 않습니다. #import는 파일을 추적하고 전 처리기가 처음으로 파일을 읽는 것을 제외하고는 #include와 같습니다.

일반적으로 오류가 발생하면 포함 된 파일의 문제로 인해 발생합니다. 그래서 아마도 ServerResponseRecord.h에 ​​오류가있을 것입니다. 아마도 실제로 선언 된 객체를 사용하여 트립되고있는 것 같습니다. 전체 헤더를 보지 않고서도 정확히 무슨 일이 일어나는지 말할 수는 없습니다.

+0

ServerResponseRecord에 문제가있는 경우 왜 유형을 id로 변경하면 코드가 컴파일되고 올바르게 실행됩니까? – tba

+0

전처리 기는 까다 롭고 일부 경우에만 확장 될 수 있지만 다른 경우에는 확장되지 않을 수 있습니다. 고립되어있는 파일을보고있는 경우, ServerRequest와 ServerResponseRecord가 유효한 정의를 가지고 있다고 가정하면 좋을 것입니다. 앞으로 @class를 사용하여이를 선언하면 어떤 경우에는 트리거하는 다른 헤더 중 하나에 잠정적 인 오류가 있음을 알 수 있습니다. –