iOS4 및 Mac OS X 10.6(snow leopard)부터 지원되기 시작한 Associated Objects.
널리 알려져 있지않지만 상당히 유용하게 사용할 수 있는 것 같다.
쉽게 설명해 보면 UIButton을 눌렀을때 파라미터를 전달하고 싶을때 간단하게 NSDictionary등의
파라미터를 같이 UIButton에 추가할 수 있다.
사용하기전에 일단 아래에 정의되어 있으니 import.
#import <objc/runtime.h>
사용은 아래의 메서드를 사용하면 된다.
objc_getAssociatedObject / objc_setAssociatedObject / objc_removeAssociatedObjects
objc_setAssociatedObject 에서 사용되는 AssociationPolicy의 종류는 아래와 같다.
enum {
OBJC_ASSOCIATION_ASSIGN = 0, // 추가된 객체와 약한 참조
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, // 추가된 객체와 강력 참조 및 nonatomatic으로 설정
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, // 추가된 객체를 복사 및 nonatomatic으로 설정
OBJC_ASSOCIATION_RETAIN = 01401, // 추가된 객체와 강력 참조 및 atomatic으로 설정
OBJC_ASSOCIATION_COPY = 01403 // 추가된 객체를 복사 및 atomatic으로 설정
}; typedef uintptr_t objc_AssociationPolicy;
객체가 추가될 때 사용된 policy가 copy나 retain인 경우는 객체가 제거될 때 해당 객체의 메모리가 release 된다.
여러 개의 객체들 중 하나만 제거하고 싶으면 해당 객체를 추가할때 사용한 key를 이용해 nil를 추가하면 된다.
Associated Objects를 이용해 copy나 retain policy로 추가된 객체들은
(objc_setAssociatedObject의 object로 넘긴) 대상 객체의 dealloc이 실행될 때 모두 release 된다.
NSObject의 subclass이기만 하다면 어떤 class의 instance에도 Associated Objects를 이용해서 객체를 추가할 수 있기 때문에
특히 UIView 의 instance 같은 UI component들에 데이터를 추가할 때 유용하다.
특정 객체에 NSDictionary 형식의 데이터 guide 를 추가하고자 한다면 다음과 같이 할 수 있다.
- (NSObject *)getProperty:(NSObject *)obj {
return objc_getAssociatedObject(obj, @"guide");
}
- (void)setProperty:(NSObject *)obj value:(NSObject *)value {
objc_setAssociatedObject(obj, @"guide", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)removeProperty:(NSObject *)obj {
objc_removeAssociatedObjects(obj);
}
또, UIAlertView의 click액션에 대해 아래와 같이 간단하게 block구문을 추가하여 처리할수도 있다.
static void *MyAlertViewKey = "MyAlertViewKey";
- (void)OnlogOut {
DLog(@"%s", __PRETTY_FUNCTION__);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"로그아웃"
message:@"정말로 로그아웃 할거냐?"
delegate:self
cancelButtonTitle:@"싫타고!"
otherButtonTitles:@"하라고!", nil];
void (^block)(NSInteger) = ^(NSInteger buttonIndex) {
if (buttonIndex == 0) {
DLog(@"LOGOUT CANCEL");
} else {
DLog(@"LOGOUT OK");
}
};
objc_setAssociatedObject(alert, MyAlertViewKey, block, OBJC_ASSOCIATION_COPY);
[alert show];
}
// UIAlertViewDelegate protocol method
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
void (^block)(NSInteger) = objc_getAssociatedObject(alertView, MyAlertViewKey);
block(buttonIndex);
}
위와같이 어떤 객체에 대해 유연하게 대처 가능한 Associated Objects 를 활용해 보자.
'DirTy™의 하루일과 > DirTy™의 가당찮은iOS' 카테고리의 다른 글
[IOS] 스토리보드를 이용한 오토레이아웃(Auto Layout) (4) | 2016.02.26 |
---|---|
[IOS] uinavigationcontroller swipe back disable 하기 (0) | 2016.01.15 |
[IOS] javascript에서 ios 로 호출하기. (0) | 2015.12.09 |
[IOS] objective-c, swift closure 구문 (0) | 2015.11.23 |
[IOS] APNS 인증서 만들기 (8) | 2015.10.27 |