2011. 4. 15. 17:30

Accessor 매서드

 클래스의 선언과 정의를 올바르게 하고, Object 루트 클래스의 alloc 메소드를 호출하면 클래스의 인스턴스가 생성됩니다.  클래스의 정의는 구조체 선언과 같은 것으로, 인스턴스를 생성하는 것은 구조체형 변수를 정의하고 구조체를 표현하는 필요한 메모리를 할당하는 행위와 유사합니다.  그러나 클래스는 멤버 변수와 그것을 처리하기 위한 전용 함수를 가진다는 점에서 구조체와는 크게 다릅니다.

 마지막 예제에서 클래스를 선언하고, 메소드를 정의하고 그것을 호출하는 작업을 수행했습니다. 예제에서의 메소드는 인수와 반환 값을 가지지 않는 단순한 것이었는데,번에 복잡한 메서드를 구현하면서 메서드에 대한 자세한 정보를 설명합니다.  특히, 메소드는 함수와는 달리, 디자인 이론의 개념에서 인스턴스와 클래스의 역할과 관련 되어 있어야 합니다.

 예를 들어, 2차원 좌표의 점을 나타내는 Point 클래스를 만들 있습니다.  경우 Point 클래스는 좌표 X Y 제공해야 합니다.  Point 클래스는 int 형식의 인스턴스 변수 x y 선언하고 값을 제어하는 메서드들을 제공해야 합니다.

 일반적으로 클래스의 인스턴스 변수는 클래스 외부에서 액세스할 없습니다.  왜냐하면, 변수가 자유롭게 변경되어 버리면, 변수의 의미와 입출력 데이터의 사양이 변경된 경우, 서비스 가능성 또는 전체 코드의 유연성이 저하되기 때문입니다.  그래서 Objective-C에서는 변수에 액세스하기 위해서는 반드시 메서드를 사용해야 합니다.  Point 클래스의 기본적인 선언은 다음과 같이 것입니다.

 

@interface Point : Object

{

  int x, y;

}

- (void) setPoint: (int) ptx : (int) pty;

- (int) getX;

- (int) getY;

@end

 

클래스의 선언은 좌표를 저장하는 변수 x y 선언하고 변수를 클래스 외부에서 접근하기 위한 메소드를 선언합니다.  setPoint 메서드는 x y 값을 변경하는 메서드이고, getX getY 메서드는 각각의 변수를 가져오기 위한 메서드입니다.  이러한 메서드를, 특히 Accessor 메서드라고 합니다.  또한 이러한 인스턴스의 멤버필드를 외부에 제공하는 정보를, 특히 속성이라고도 합니다.

 인수를받는 메서드는 인수 형을 () 안에 지정하고 다음에 형식 인수의 이름을 지정합니다.  () 배웠던 것과 마찬가지로 형식을 지정하지 않으면 기본 반환값인 id 형식을 기본으로 반환합니다.  하나 이상의 인수가 있으면 추가로 콜론 : 다음에 지정합니다.  보다 구체적으로는, 메소드의 선언은 다음과 같습니다.

 

 - (반환 형식) 메서드 이름 : (인수 형식) 변수 이름 레이블 : ...

 

 여러 인수를 받는 메서드는 변수 이름 다음에 레이블을 지정할 있습니다.  Objective-C 세계에서는 레이블을 지정할 있지만 레이블과 콜론은 메서드 이름의 일부로 인식되는 것입니다.

 레이블과 콜론이 이름의 일부로 인식되기 때문에 Objective-C에서는 동일한 매개 변수, 메서드 이름을 가진 메서드를 구분하여 호출할 있습니다.  예를 들면 (void) setPoint : (int) : (int)라는 메서드는 (void) setPoint : (int) label : (int) 메소드와는 다른 메서드로 선언 정의할 있습니다.

 인수가있는 메서드를 호출하려면 메시지 식에서 메서드 이름 뒤에 인수로 전달할 값을 지정합니다.  레이블을 지정하지 않는 setPoint 경우 [obj setPoint x : y] 형태로 호출하며, 레이블을 지정하는 경우에는 [obj setPoint : x label : y] 형태로 호출합니다.  인수 개수 라벨이 다르다면 메서드 이름이 같더라도 구분하여 호출할 있는 구조입니다.  특정 기능을 제공하는 메소드를 다양한 형태로 제공하고 싶은 경우에 레이블이 필요합니다.  setPoint 메서드를 int 형식이 아닌 형식으로 사용 하고자 하는 경우 이방법은 중요한 것입니다.

 #import <stdio.h>

 #import <objc/Object.h>

 

 @interface Point : Object

 {

   int x, y;

 }

 - (void) setPoint : (int) ptx int : (int) pty;

 - (int) getX;

 - (int) getY;

 @ end

 

 @ implementation Point

-   (void) setPoint : (int) ptx int : (int) pty

  {

   x = ptx;

   y = pty;

  }

 - (int) getX {

   return x;

 }

-   (int) getY {

   return y;

 }

 @end

 

 int main()

 {

   id point1, point2;

   point1 = Point alloc];

   point2 = Point alloc];

 

   [point1 setPoint : 16 int : 32];

   [point2 setPoint : 256 int : 128];

 

   printf ( "point1 : X = % d Y = % d \ n", point1 getX], [point1 getY]);

   printf ( "point2 : X = % d Y = % d \ n", point2 getX], [point2 getY]);

   return 0;

 }

  프로그램의 Point 클래스는 2개의 정수형 인수를 가지는 setPoint : int : int 메서드와 좌표값을 반환하는 getX, getY 메서드를 선언하고 있습니다.  setPoint 메서드 선언은 setPoint (int) ptx : (int) pty라고 해도 문제가 되지 않지만 향후 setPoint 확장하는 것을 생각한다면 레이블을 지정하는 것이 좋습니다.

 main() 메서드는 alloc 메소드를 사용하여 Point 타입의 클래스 인스턴스를 2 생성하고 있습니다.  point1 변수 point2 변수가 가리키는 인스턴스는 서로 다르기 때문에 인스턴스에 설정한 값은 별도의 메모리에 저장되고 있다는 것이 출력물에서 확인할 있습니다.

 

 암시적 self

 메서드에는 형식 인수와 선언된 변수 이외에 절대적인 변수로 self 제공하고 있습니다.  self 변수는 id 형식으로 항상 메서드를 호출하는 인스턴스 변수를 참조하고 있습니다.  , 메서드를 실행하는 객체 자신을 나타내는 변수가 self입니다.

 self 메소드 이외의 장소에는 사용하지 못하고, 항상 메서드와 함께 사용 해야 합니다. 실행 코드 에서만 암시적으로 존재하는 형태로 되어 있습니다.  self 사용하여 객체의 인스턴스 변수에서 객체 자신을 참조 있습니다. 이것은 메서드의 형식 인수의 변수 이름이 인스턴스 변수 이름을 은폐할 경우에 이용할 있습니다.  Accessor 메서드에서 가장 자주 사용하게 것입니다.

  #import <stdio.h>

  #import <objc/Object.h>

 

 @interface Point : Object

 {

   int x, y;

 }

 - (void) setPoint : (int) ptx int : (int) pty;

 - (int) getX;

 - (int) getY;

 @end

 

 @implementation Point

-   (void) setPoint : (int) x int : (int) y

  {

   self -> x = x;

   self -> y = y;

  }

  (int) getX

  {

   return x;

  }

  (int) getY

  {

    return y;

  }

 @end

 

 int main()

 {

   id point1, point2;

   point1 = Point alloc];

   point2 = Point alloc];

 

   [point1 setPoint : 32 int : 64];

   [point2 setPoint : 256 int : 128];

 

   printf ( "point1 : X = % d Y = % d \ n", point1 getX], [point1 getY]);

   printf ( "point2 : X = % d Y = % d \ n", point2 getX], [point2 getY]);

   return 0;

  }

  프로그램의 setPoint : int : int 메서드는 형식 인수로 선언된 이름과 인스턴스 변수 x y에서 이름 충돌이 일어나고 있습니다(같은이름의 변수).  자체는 문제가되지 않지만 메서드 범위에서는 인스턴스 변수가 무시되어 버립니다.  따라서 인스턴스 변수에 접근하기 위한 수단으로 현재의 메서드를 실행하는 객체를 참조하는 self 변수를 사용합니다.  클래스 외부에서 인스턴스 변수를 없지만 메서드는 클래스의 내부이므로 객체에서 직접 인스턴스 변수에 액세스할 있습니다.  프로그램은 self -> x 형태로 인스턴스 변수에 전달된 데이터를 참조합니다.

 또한 메서드에서 동일한 인스턴스의 다른 메소드를 호출할 때도 self 필요합니다.

 #import <stdio.h>

 #import <objc/Object.h>

 

 @interface Test : Object

 - (void) methodA;

 - (void) methodB;

 @end

 

 @implementation Test

-   (void) methodA

   {

   printf ( "method A \ n");

   [self methodB];

   }

-   (void) methodB

   {

    printf ( "method B \ n");

    }

 @end

 

 int main()

{ 

  [Test alloc] methodA];

   return 0;

}

  프로그램의 Test 클래스는 methodA 메서드 methodB 메서드를 self 객체를 사용하여 호출합니다.  self methodA 실행하는 인스턴스이므로 동일한 인스턴스의 methodB 호출하는 것입니다.

Posted by openserver