본문 바로가기

iOS/Objective-C

Objective-C) Category와 Extension

 

 

 

안녕하세요 :) 소들입니다!

오늘은 Objective-C에서 카테고리라는 놈에 대해 알아보려고 해요!!!

카테고리라.. 저는 처음에 듣고 되게 생소하다.. 느꼈던 거 같아요

뭔가 다른 언어에서 볼 수 없는 Objective-C만의 느낌이 강해서 그런가

 

쨌든..!

오늘은 이 카테고리가 무엇인지에 대해 알고,

또 Objective-C의 Extension까지 같이 다뤄보려고 해요 :)

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

1. 카테고리가 뭐야?

 

먼저, 카테고리의 정의에 대해 알고 가겠음!!!!

 

카테고리는 기존에 정의된 클래스를 쉽게 확장할 수 있게 해주는 기능이다

 

어..? 말로만 들으면 Extension이랑 다를 게 모람..? 싶겠지만,

사실 좀이따 배울 Objective-C의 Extension은 이 Category 범주 중 하나임!!!

(이건 좀이따 Extension 할 때 설명)

 

예로 설명해보면,

자 우리가 만약 NSString이라는 클래스를 확장하고 싶음

다음과 같이

 

영어 처리, 한국어 처리, 일본어 처리

 

세 언어에 대한 간단한 기능들을 확장을 하고 싶음

근데 원래대로 확장을 한다면 NSString이란 확장 클래스 안에

 

 

 

 

이렇게 세 언어에 대한 기능이 다같이 추가 구현되어 있을 거잖음??

근데 만약 다음과같이

 

EnglishClass

KoreanClass

JapaneseClass

 

총 3개의 클래스가 있다고 쳐보셈 그러면

 

EnglishClass에선 영어 처리만 필요하고,

 KoreanClass에선 한국어 처리만 필요하고,

JapaneseClass에선 일본어 처리만 필요한데

 

근데 저렇게 세 언어 처리를 모두 NSString의 전체로 확장하기 너무 별로!!! 싶지 않음??

바로 이럴 때 사용하는 것이 바로 카테고리임!!

 

내가 원하는 클래스에 특정 기능만 확장 시키는 것

 

 

 

 

이것이 바로 카테고리

 

엥 그냥 서브 클래싱 해서 쓰면 안되나염? ㅎㅎ 할 수 있는데,

카테고리는 말 그대로 기존 클래스를 확장하는 것임!!!!!

우리가 알던 확장과 좀 다르다면, 카테고리를 구분하는 확장일 뿐

 

따라서, 굳이 서브 클래싱 해서 새로운 클래스로 만들어서 사용하는 것이 아닌,

기존 NSString 클래스에다가 원하는 기능을 (마치)카테고리 별로 추가해서 사용하는 것 뿐임

(서브 클래싱보다 좋은점은 밑에서 카테고리 장점 쓸 때 설명 하겠음)

 

그렇다면 카테고리가 뭔지 알았으니

어떻게 사용하는지 이제 봐보자 :)

 

 

 

1-1. 카테고리 만드는 방법

 

카테고리를 사용하는 방법은 보겠음

먼저, 카테고리로 사용할 클래스를 하나 추가해주는데,

 

 

 

 

자, 여기서 중요한거 Objective-C에서 카테고리를 사용할 경우,

네이밍 규칙이 있음 (반드시 따라야 하는 건 아니고)

 

확장시킬 클래스 이름+카테고리명

 

이런 식으로 생성함!!!!! 저 + 는 합치라는 게 아니라

진짜 "+"를 써서 이름을 만듦!! (위 사진처럼)

 

 

 

 

자, 이렇게 만들어졌다면 성공 :)

그럼 이제 헤더파일과 구현부 파일을 어떻게 작성하는지 보겠음

 

 

 헤더 파일(.h) 

 

자, 기존 구현되어 있는 헤더파일을 바꿔주어야 하는데,

@interface 옆 부분을 다음과 같이 바꿔줌

 

 

 

 

이런 식으로

 

@interface 클래스이름 (카테고리명)

 

그럼 헤더파일 끝!

아, 헤더파일에서 중요한 걸 잊었네

 

 

① 카테고리에선 인스턴스 변수를 추가할 수 없다

 

 

 

 

Asscosiative References라는 것을 사용하면 인스턴스 변수를 추가할 수 있다는데,

나중에 찾아보고 따로 포스팅 하겠음!

 

 

② 카테고리에서 프로퍼티는 추가할 수 있다

 

인스턴스 변수는 추가할 수 없지만, 프로퍼티는 추가할 수 있음!

근ㄷ ㅔ이런식으로 추가해주면

 

 

 

 

되는데, 이렇게 추가할 경우 노란 오류 메세지가 두개 뜸

 

 

 

 

해당 프로퍼티의 getter, setter가 없다고 생성하라는 오륜데

(Property의 경우 자동으로 생성해주는 거 아닌가 싶은데, 

카테고리는 임의의 확장 클래스라서 init이 안되는건가..;;? 잘 모르겠음)

 

쨌든 해결하기 위해선 해당 프로퍼티를 @dynamic으로 선언해주든가

 

 

 

 

아니면 name이라는 프로퍼티의 getter, setter를 직접 만들어주든가,

 

 

 

하면 됨!!! :)

(@dynamic의 용도나 왜 getter, setter를 직접 만들어줘야되는지는

공부 더하고 나중에 따로 포스팅 해보겠음............)

 

 

 

 구현부 파일(.m) 

 

자, 기존에 이런 식으로 되어 있는 구현부 파일 또한

헤더 파일과 똑같게 다음과 같이 바꿔줌

 

 

 

 

@implementation 클래스이름 (카테고리명) 

 

으로 해주면, 구현부 파일도 끝!

 

 

이제 카테고리에 원하는 기능을 알아서 구현 해주셈 :)

클래스 메서드, 인스턴스 메서드 모두 구현 가능! (마찬가지로 변수는 선언 안됨)

 

 

 

1-2. 카테고리 사용법

 

자, 이제 이 확장된 카테고리를 사용하기 위해선

사용하고자 하는 클래스에서 카테고리를 import 하는 작업을 해야함

 

 

 

 

이렇게!! 

그러면 내가 추가한 카테고리의 메서드를

 

 

 

 

사용 가능함:) 호호호호

 

내가 import한 카테고리의 확장된 메서드만 사용할 수 있기 때문에

English 클래스에서 NSString+English 만 import 했다면,

NSString+Korean, NSString+Japanese에서 확장된 메서드는 사용할 수 없음!

 

 

 

1-3. 카테고리 주의점

 

이번엔 카테고리를 사용할 때 주의할 점에 대해 말하겠음

 

 

 Overriding 주의 

 

기존 클래스에 존재하는 이름과 똑같은 이름의 메서드를 카테고리에 선언할 시,

카테고리에서 정의한 메서드로만 실행되어버림!!!

(서브 클래싱이 아니기 때문에 super를 호출할 수도 없음!!!)

 

물론, 해당 카테고리를 import 하고 있다면 말임!

근데 웬만해선 Overriding 하지 않게 조심하자 :)

 

 

 카테고리 내 메서드 이름은 다 다르게 해주자

 

만약 서로 같이 import 될 일 없는 카테고리면 상관 없지만,

같은 메서드 이름을 가진 카테고리가 같이 import 되면,

두 개의 카테고리 중 어떤 메서드가 불릴지 장담할 수 없음!!

 

따라서 안전하게 이름을 달리 해주자 :)

 

 

 

1-4. 카테고리의 장점

 

따로 클래스를 만들거나(서브클래싱), 복잡한 구조 없이 간단하게

클래스의 메소드들을 기능별로 모듈화 할 수 있어

클래스의 의존성도 줄어들고, 어플리케이션의 전체 구조가 간결하게 정리됨

 

서브클래싱은 상속으로 인해 가계도가 커지고,

오버라이딩 되는 멤버가 많을 수록 관리상의 어려움과 성능 이슈가 발생하여

Objective-C는 서브 클래싱보다 다른 방법으로 객체 확장을 장려하는 편임

 

근데 일반 확장과 달리 일일이 필요한 카테고리를 import 해줘야 하는 건

 좀 귀찮은듯...........

 

 

 

 

2. Extension (확장)

 

아까 내가 카테고리를 설명할 때 이 Extension을 뭐라 했냐면,

Extension은 카테고리의 범주 중 하나라고 했음

맞음 Extension은

 

익명 카테고리

 

라고 생각하면 됨 :)

우리가 Swift에선 일반적으로 앞에 

 

 

 

 

우린 이것을 구현하려면, 익명 카테고리를 구현하면 되는 것임!!!

 

 

 

2-1. Extension 만드는 방법

 

음.......근데 Objective-C에서는 카테고리란 기능 때문에

Extension 자체를 잘 안쓰는 거 같고

지금 테스트 해보니까 되게 특이함;;;

 

먼저,

해당 클래스의 구현부(.m) 파일 내에서만 Extension이 가능함...

 

내가 해봤을 때 카테고리처럼 따로 클래스를 만들어서 하는 건

불가능하고 그런 예제도 없는데 혹시라도 있음 알려주3

 

어떤 식으로 하냐면

 

 

 

 

이렇게, 해당 클래스 @implementation 위에다가 (아래다 하면 안됨)

익명 카테고리를 선언해주는데, 익명이므로 () 선언해 주는 것임

 

여러분.. 요거요거 어디서 많이 봤다고 느끼셔야 하는데

우리가 아무렇지 않게 ViewController 만들고 구현부 파일 들어가면

 

 

 

자동으로 생성되어 있던 저 부분이 바로

 Extension 즉, 익명 카테고리였던 것임...

걍 지우고 썼는데;; 이것도 모르고 여태껏 개발을 했었다니..... (자괴감)

 

모든 Cocoa Class가 자동 제공되는 것 같진 않고,

몇몇 개 ViewController같은 것들만 Extension이 자동 제공되는 것 같음

 

 

 

2-2. Extension은 왜 쓸까

 

근데, Extension이라고 저렇게 추가 했지만

실제 Extension 함수라고 해도 기존 클래스와 같이 implementation에다 작성해야 됨

 

...

그럼 Extension은 왜 쓰는 걸까...?

 

Extension Interface에 정의한 메서드나 프로퍼티는

Private으로, 내부 클래스에서만 접근 가능하다

 

그렇군..

Objective-C에서의 Extension은 우리가 아는 개념하고 좀 많이 다른 것 같음..;;

Private Interface를 만들고 싶을 때 사용함

실제로

 

 

 

 

Extension에서 작성한 프로퍼티 name은,

 

 

 

 

외부에서 접근 불가하며,

 

 

 

 

이렇게 클래스 내부에서만 사용 가능함..!

프로퍼티 외에 메서드도 마찬가지임..!!!

 

음..... 프로퍼티로 구현은 해야하지만, 외부에서 감추고 싶을 때나

메서드의 프로토타입을 감추고 싶을 때 사용한ㄷ ㅏ함....

(굳이 Private로 정의 안해도 헤더 파일에 선언 안 하면

감추면서 내부에선 잘 쓸 수 있지 않나.............ㅜㅜ?)

 

Extension은 어리둥절 한 부분이 많아

나중에 더 자세히 알게되면 추가 하겠습니다.......... 🥵

 

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday