ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS/Objective-C] NSCopying과 NSCoding의 차이를 알아보자.
    앱등이에게 살충제를 뿌린다./Objective-C 2016. 1. 7. 23:20


    <인도와 인도네시아의 차이에 대해 물어본다면 난 딱히 할말이 없다.>



    NSCopying과 NSCoding

    이름만 들으면 무언가 Array와 Dictionary마냥 유사한 부분이 있을것 같네요.

    하지만 그렇지 않아요.


    개념만 짚도록 해볼게요.


    1. NSCopying

    copy메소드 아시죠? NSObject에 구현되어 있기 때문에 모든 객체에서 사용이 가능합니다.

    이런 클래스가 있다고 가정합시다.



    그리고 copy를 시도합니다.

    unused variable이라는 경고만 있을 뿐, 에러가 발생하지 않습니다.

    당연하죠. Person에는 copy메소드가 구현되어 있을테니까요.

    실행해보겠습니다. 



    음.. 같이 웃으며 망년회하던 HR에서 권고사직을 권하는듯한 통수네요.

    하루종일 아무일 없다가 함수를 실행하자마자 이렇게...  왜그럴까요?



    copy메소드를 실행하면 NSCopying프로토콜에 있는 -(instancetype)copyWithZone:(NSZone *)zone 메소드가 실행됩니다.(zone : 시스템에서 지정한 메모리공간)

    하지만 위에 있는 Person클래스는 NSCopying 프로토콜을 따르지 않고 있습니다.

    NSCopying프로토콜을 따르지 않는 다는건 -(instancetype)copyWithZone:(NSZone *)zone 메소드도 구현되어 있지 않다는 뜻입니다.

    구현하지도 않은 -(instancetype)copyWithZone:(NSZone *)zone메소드를 copy메소드 내에서 호출을 하고 있으니 오류가 발생한 것입니다.

    그럼 프토콜을 따르게 하여 문제를 해결해보겠습니다.



    이 상태로 다시 실행하면 오류가 발생하지 않고 복사된 객체가 대입됩니다.

    NSCopying. 이해되셨나요?

    NSCopying프로토콜을 따르지 않는 클래스(우리가 만드는 대부분의 클래스)는 copy메소드를 실행하기 위해 NSCopying프로토콜을 구현하는 것입니다.





    2. NSCoding

    NSCoding은 객체 아카이빙과 관련되어 있습니다. (아카이빙 : 객체를 나중에 재사용하기위해 저장하는 절차)

    이렇게 보면 NSCopying과 NSCoding은 굳이 연관지을 필요가 없어보입니다.


    객체를 파일에 아카이빙하기 위해 

    를 사용할 수 있습니다.


    실행해 볼게요?

    역시나 깔끔하게 비수가 날아와 가슴에 꽂힙니다.



    감이 오셨나요?

    NSCoding프로토콜을 구현해주어야 합니다.

    Foundation에서 제공하는 NSString, NSArray, NSDictionary, NSDate 등의 클래스는 이 프로토콜을 구현하기 때문에 만약 제가

    위와 같이 NSString객체를 사용했다면 실행이 잘 되었을거에요.


    Person클래스은 NSCoding프로토콜을 따르지 않기때문에 아카이빙에 필요한 인코딩 작업이 진행되지 않았던 것입니다.

    그렇다면 NSCoding프로토콜의 -(void)encodeWithCoder:(NSCoder *)aCoder 메소드를 구현해보겠습니다.


    NSCoding프로토콜을 구현했으므로 이제 정상적으로 실행이 됩니다.

    사실 이 encodeWithCoder메소드 내부에서 멤버들을 encode하는 작업을 해주어야 하지만, 생략하도록 하겠습니다.

    외에도 언아카이빙을 하기 위한 - (instancetype)initWithCoder:(NSCoder *)aDecoder메소드가 있지만 생략하도록 하겠습니다.


    이상 NSCopying과 NSCoding의 차이라면 차이라고 할 수 있는 점에대해서 알아보았습니다.

    음.. 끝!


    댓글 3

    • OH 2017.02.08 10:59

      정리 잘 해두셔서 글 잘 보고 있습니다.
      Person객체에 property가 있다면 이런식으로 처리할 수 있다라는 부분도 댓글 달아봅니다.^^

      @interface Person : NSObject <NSCopying>

      @property (nonatomic, copy) NSString *name;
      @property (nonatomic, assign) NSUInteger age;

      @end

      implementation Person

      - (instancetype)copyWithZone:(NSZone *)zone
      {
      Person *person = [[Person allocWithZone:zone] init];
      person.name = self.name;
      person.age = self.age;
      return person;
      }

      @end

      • 고무망치 2017.02.08 13:54 신고

        OH님께서 해주신 방법으로 복사를 하게되면 shallow copy가 되겠네요. 프로퍼티마저 copy한다면 deep copy가 되겠구요.

        글도 봐주시고 첨부까지해주셔서 감사합니다^^

    • 허접코더 2019.09.28 10:50

      재밌게 잘보고갑니다.
      글을 참 찰지게 쓰시네요 ㅎㅎㅎㅎ

Designed by Tistory.