posted by By훈트 2011.01.07 12:43

Protocol Java interface 같다 어떤 protocol 따르는(adopting하는클래스는 protocol에서 선언된 모든 메소드들을 구현해야한다.


  다음은 object copy하는 copyWithZone 메소드가 담긴 NSCopying protocol 선언과 이것을 adopt하는 클래스의 @interface이다.


    @protocol NSCopying


    - (id) copyWithZone: (NSZone*) zone;


    @end



    @interface Car : NSObject <NSCopying> // <NSCopying, NSCoding> 같이 

                                                                // 여러개의 protocal adopt 수도 있다.

    {

        // instance variables...

    }


    // methods...

    // protocol 안에 선언되어 있는 메소드는 따로 다시 선언할 필요 없다.


    @end



  copyWithZone 메소드의 zone 할당할 메모리 영역을 나타내는 NSZone 타입의 매개변수이다. object copy 메소드를 호출할 경우내부적으로 copyWithZone 메소드로 변환되어 호출된다따라서 클래스에 따라  copyWithZone 메소드를 구현함으로써  클래스에 맞는 올바른 copy 되도록   있다.


  다음은 <NSCopying> adopt하여 deep copy 되도록 하는 Engine, Tire, Car 클래스의 copyWithZone 메소드 구현이다.@interface 부분은 생략하겠다.


    @implementation Engine


    - (id) copyWithZone: (NSZone*) zone

    {

        /* allocWithZone 메소드는 NSObject 클래스의 class method로서

         * 해당 클래스의 새로운 객체를 생성한다.

         * 객체 자신이 아닌 [self class] 사용함으로써 

         * subclass 역시 [super copyWithZone] 호출하여 copy 사용할  있다. */

        // Engine instance variable 가지지 않으므로 instance variable copy 과정 없이

        // 바로 init으로 초기화하면 된다.

        Engine* engineCopy = [[[self classallocWithZone:zone] init];

        return engineCopy;

    }


    @end


    @implementation Tire


    - (id) copyWithZone: (NSZone*) zone

    {

        Tire* tireCopy = [[[self classallocWithZone: zone]

                          initWithPressure: pressure treadDepth: treadDepth];

        return tireCopy;

    }


    @end


    @implementation Car


    - (id) copyWithZone: (NSZone*) zone

    {

        Car *carCopy = [[[self classallocWithZone: zone] init];

        

        carCopy.name = self.name;

        

        // engineCopy copy 의해 생성된 것이므로 memory management rule 의하여 release까지 책임을 져야 한다.

        // 여기에서는 autorelease 걸어주었다.

        Engine* engineCopy = [[engine copyautorelease];

        carCopy.engine = engineCopy;

        

        int i;

        for(i = 0; i < 4; i++)

        {

            Tire* tireCopy = [[self tireAtIndex: i] copy];

            // tire역시 copy 생성되었으므로 autorelease 걸어준다.

            [tireCopy autorelease];

            

            [carCopy setTire:tireCopy atIndex:i];

        }

        

        return carCopy;

    }


    @end




  앞서 id 타입은 어떠한 object 가리킬  있는 generic 타입이라고 설명하였다다음과 같이 id protocol 붙여줌으로써 protocol 만족하는 object들만을 가리키게   있다.


    - (void) setObjectValue: (id<NSCopying>) obj;



  Objective-C 2.0 이후부터는 protocol 선언에 @optional @required라는 modifier 추가되었다@optional  구현하지 않아도 괜찮은 메소드들을 나타내고( 장에서 설명한 informal protocol처럼), @required 기존의 protocol 선언된 메소드들처럼  구현되어야 하는 메소드들을 나타낸다


    @protocol BaseballPlayer


    - (void) slideHome;

    - (void) catchBall;

    - (void) throwBall;


    @optional

    - (void) drawHugeSalary;


    @required

    - (void) swingBat;


    @end




Reference

[1] Dalrymple. M., Learn Objective-C on the Mac, Apress.



저작자 표시
신고