본문 바로가기

iPhone

ios 카테고리(category)

기존의 클래스에서 상속이 아닌 확장의 개념으로 사용하는 개념. 상속이아닌 확장의 개념이기 때문에 superclass를 사용하지 않고 기존클래스 사용이 가능하며 또한 변수 추가가 불가능하며 메서드만 추가 가능하다. (예를들어 UIButton에 -(void)changeImage라는 메서드를 추가 한다고 가정 하였을 때 버튼에서 해당 메서드를 사용 하려면 UIButton을 상속받은 class로 변경 해 주어야 했지만 카테고리를 사용한다면 #import "UIButton+확장이름.h" 사용하려는 해당 클래스에 선언만 해주면 UIButton에서  -(void)changeImage를 바로 사용이 가능하다.)


사용 예시 (UIButton 확장을 예로..)

UIButton+확장이름.h

@interface UIButton (확장이름)

- (void)changeImage;

@end

UIButton+확장이름.m

#import "UIButton+확장이름.h"

@implementation UIButton (확장이름)

- (void)changeImage{

    [self setBackgroundImage:[UIImage imageNamed:@"bg.png"] forState:UIControlStateNormal];

}

@end


카테고리에서 변수 추가는 불가능하지만 Associated Objects(objc_setAssociatedObject)을 사용하여 추가하는 방법이 있다. 

아래는 UIButton에 NSString과 NSDate를 추가하는 예제이다.


UIButton+UIButton_Date.h

#import <UIKit/UIKit.h>

#import <objc/runtime.h>

@interface UIButton (UIButton_Date)

@property (nonatomic, strong) NSDate *date;

@property (nonatomic, strong) NSString *btnState;

@end


UIButton+UIButton_Date.m

#import "UIButton+UIButton_Date.h"

@implementation UIButton (UIButton_Date)

- (void)setDate:(NSData *)date

{

    objc_setAssociatedObject(self, "_date", date, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSData *)date

{

    return objc_getAssociatedObject(self, "_date");

}

- (void)setBtnState:(NSString *)btnState

{

    objc_setAssociatedObject(self, "_btnState", btnState, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSString *)btnState

{

    return objc_getAssociatedObject(self, "_btnState");

}

@end


카테고리를 사용할 클래스의 해더에 #import "UIButton+UIButton_Date.h"를 추가해 준다면 UIButton에서 date와  btnState를 @synthesize를 선언한 것처럼 접근이 가능한 것을 알 수 있다.



카테고리 참조 : https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html


Associated Objects 정리가 잘되있는 블로그 : http://minorblend.com/post/40590130886