2009-06-22 1 views
7

Objective-C 클래스의 구현 블록 (@implementation ... @end) 내부 또는 외부에서 선언 된 C 함수 (정적 또는 비공유)의 차이점은 무엇입니까?Obj-C : @implementation 블록의 내부 또는 외부에서 선언 된 C 함수는 무엇입니까?

는 직접 객체의 내부에 찌를 필요가 있다면, 당신은 당신의 클래스의 @implementation 블록의 내부에이 기능을 넣을 수 있습니다, 그리고 당신이 인스턴스 변수에 액세스 할 수 있습니다

?이 특별히 사실이다 C 화살표 연산자. 하지만 그건 장난이 아니므로, Purity of Essence를 유지하려면 개체에 메서드 호출을 사용해야합니다. 설교의 끝.

@implementation OblateSphereoid 

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData) 
{ 
BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData; 
dealie->_frognatz = [NSColor plaidColor]; 
// and more stuff. 
} // drawEggThunk 

... 
@end // OblateSphereoid 

내가 이런 식으로 기능 (같은 클래스에서 선언) 내에서 내 클래스의 인스턴스 변수에 액세스 할 수 있습니다 : 여기에 악입니까?

+0

재미있는 질문인데 (아마도 아주 나쁜 습관 일지라도) 호기심 때문에, 수업 내에서만 drawEggThunk를 호출 할 수 있습니까? –

+0

콜백이 설정되어있을 때 self에 대한 참조를 전달하기 위해 * userData를 사용하는 것을 볼 수 있듯이 함수는 C 서브 시스템에서 호출되는 콜백 함수입니다. – jlpiedrahita

답변

2

이것이 합법적 인 반면 설명이 필요한 경우 왜 필요한지 이해할 수 없습니다 (추한 해결책입니다). 왜 그냥 호출 할 수 없습니다 :

[dealie setFrognatz:[NSColor plaidColor]]; 

당신은 일반적으로하지만,이 함수 정의 위에 그냥하는 .m 내부를 선언함으로써 그것을 개인 방법을하는 -setFrognatz:를 제공하지 않는 경우. (이이 경우에 @implementation 블록의 경우 실제로 문제가되지 않습니다.) -> 표기법 도움이 될 수있는 몇 곳이 있습니다

@interface BWOblateSphereoid() 
- (void)setFrognatz:(NSColor *)acolor 
@end 

@implementation OblateSphereoid 

void drawEggThunk (DrawingContext *context, Rect areaToDraw, void *userData) 
{ 
    BWOblateSphereoid *dealie = (BWOblateSphereoid *)userData; 
    [dealie setFrognatz:[NSColor plaidColor]]; 
    // and more stuff. 
} // drawEggThunk 

... 
@end // OblateSphereoid 

. 가장 중요한 것은 absolutely required이 될 수있는 -copyWithZone:을 구현하는 것입니다 (NSCopyObject()과 같은 원시 메모리를 사용하여 재생되는 ObjC 코드를 싫어하는 요구 사항). 하지만 항상 접근자를 추천하는 것과 같은 이유 때문에 대부분의 경우 ->을 사용하는 것이 좋습니다. C 함수 (다른 일반적인 용도 인 ->)를 참조하여 ivar을 전달해야하는 경우에도 임시를 사용하여 나중에 할당하는 것을 선호합니다.

내가 ObjC에서 버그가 수 있도록 인스턴스 변수는 기본적으로 @private하지 않은 사실을 고려 .... 나는 모든 @interface 블록의 상단에 @private을 넣고 그런 식으로 몇 가지 불쾌한 버그를 피할 수있다.

현재로 작성한 솔루션이 NSColor으로 누출 될 수 있습니다. 어쩌면 그렇지 않을 수도 있지만 접근자가 확실 할 수 있습니다.

+0

"개인"방법은 근본적인 문제 (끊김없는 캡슐화없이 함수 내에서 ivars에 액세스)에 대한 해답입니다. :)하지만 ... 내부 및 외부의 @impementation 함수에는 약간의 차이가 있습니까? 그런데 – jlpiedrahita

+0

그런데 objc ivars는 기본적으로 @protected입니다.이 클래스는 클래스 자체 및 하위 클래스에서 볼 수 있으며 나머지 클래스에서는 숨겨져 있습니다. – jlpiedrahita

+0

@implementation의 내부와 외부에는 아무런 차이가 없습니다. –

2

내부에 @implementation이 있으면 제대로 작동합니다. 나는 당신이 그것을 정상적인 방법으로 만들 것을 권하고 싶지만 작동한다.

구현에서 제외하면 경고 메시지가 나타납니다. 경고 : 인스턴스 변수 ''가 @protected입니다. 이것은 앞으로는 어려운 오류가 될 것입니다. 당신과 같이 ... 헤더에 바르 전에 @public를 넣어이 오류를 방지 할 수 있습니다 : 당신이 객체가 경고없이 나타납니다 구조체 곳마다 C (포인터)와 같은 변수에 액세스 할 수 있습니다

@public 
int myInt; 

합니다.

그래서 그 doable, 권장하지 !!!

+0

나는 이것이 나쁜 습관일지도 모르지만 나는 단지 캡슐화에 찬성하여 공개로 ivar를 노출하고 싶지는 않지만 내 C 콜백 함수는 인스턴스 ivars를 볼 수 있어야합니다. – jlpiedrahita

+0

다음해야 할 일을해야합니다 ... 모든 iVars를 공개로 선언 할 필요는 없습니다. 혼합하여 일치시킬 수 있습니다. – micmoo

관련 문제