Associated Objects

9618 단어

Associated Objects


Written by Matt Thompson 작성, Croath Liu 번역, 2014년 2월 10일 발표

#import <objc/runtime.h>

Objective-C 개발자는 이 위험한 주문의 각종 준칙을 조심스럽게 따라야 한다.하나의 좋은 원인은 혼란스러운 운행을 할 때 코드가 그 구조 위에 운행하는 모든 코드를 바꾸는 것이다.
이로운 측면에서 볼 때<objc/runtime.h> 중의 함수는 다른 방식으로는 할 수 없는, 응용과 프레임워크에 강력한 기능을 제공할 수 있는 능력을 가지고 있다.폐해의 측면에서 볼 때 코드의sanitymeter를 파괴할 수 있고 모든 코드와 논리가 매우 나쁜 부작용(terrifying side-effects)에 영향을 미칠 수 있다.
그래서 우리는'악마와의 거래'(Faustian bargain)에 대해 커다란 두려움을 품고 생각한다. NS힙스터 독자들이 가장 많이 요구하는 주제 중 하나인 대상 관련(associated objects)을 살펴보자.
객체 연관(또는 연관 참조라고도 함)은 원래 Objective-C 2.0이 실행될 때의 특성으로 OS X Snow Leopard 및 iOS 4에서 시작됩니다.관련 참조에서는 <objc/runtime.h>에 정의된 다음 세 가지 키 값을 런타임 시 객체에 연관시킬 수 있는 함수를 볼 수 있습니다.objc_setAssociatedObject objc_getAssociatedObject objc_removeAssociatedObjects
왜 내가 이게 유용하다고 했지?이것은 개발자가 이미 존재하는 클래스에 사용자 정의 속성을 추가할 수 있도록 하기 때문에, 이것은 Objective-C의 가장 큰 단점을 거의 보완했다.

NSObject+AssociatedObject.h

@interface NSObject (AssociatedObject)
@property (nonatomic, strong) id associatedObject;
@end

NSObject+AssociatedObject.m

@implementation NSObject (AssociatedObject)
@dynamic associatedObject;

- (void)setAssociatedObject:(id)object {
     objc_setAssociatedObject(self, @selector(associatedObject), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (id)associatedObject {
    return objc_getAssociatedObject(self, @selector(associatedObject));
}

일반적으로 추천하는 방법은 첨가된 속성static char 유형이 가장 좋고 지침형이 가장 추천된다.일반적으로 이 속성은 상수, 유일, 적용 범위 내에서 Getter와 setter로 접근해야 한다.
static char kAssociatedObjectKey;

objc_getAssociatedObject(self, &kAssociatedObjectKey);

그러나 더 간단한 방식으로 실현할 수 있다: selector로.
Since SELs are guaranteed to be unique and constant, you can use _cmd as the key forobjc_setAssociatedObject(). #objective-c #snowleopard — Bill Bumgarner (@bbum)  August 28, 2009

연관된 객체의 동작


속성은 열거 유형objc_AssociationPolicy에 정의된 동작에 따라 객체에 연관될 수 있습니다.
Behavior
@property Equivalent
Description
OBJC_ASSOCIATION_ASSIGN
@property(assign) 또는 @property(unsafe unretained)
관련 대상의 약한 인용을 지정합니다.
OBJC_ASSOCIATION_RETAIN_NONATOMIC
@property (nonatomic, strong)
관련 대상의 강력한 인용을 지정합니다. 원자화할 수 없습니다.
OBJC_ASSOCIATION_COPY_NONATOMIC
@property (nonatomic, copy)
관련 대상의copy 인용을 지정합니다. 원자화할 수 없습니다.
OBJC_ASSOCIATION_RETAIN
@property (atomic, strong)
원자화할 수 있는 관련 대상의 강력한 인용을 지정합니다.
OBJC_ASSOCIATION_COPY
@property (atomic, copy)
원자화할 수 있는 관련 대상의copy 인용을 지정합니다.OBJC_ASSOCIATION_ASSIGN 유형으로 대상에 연결된 약한 인용은 0retian의weak 약한 인용을 대표하지 않으며 행동상unsafe_unretained 속성과 비슷하기 때문에 당신의 시선에서 weak의 관련 대상을 호출할 때 상당히 조심해야 한다.
WWDC 2011에 따르면 세션 322(36분께)에 게시된 메모리 폐기 일정에 따르면 연관된 대상은 라이프 사이클에서 대상 자체보다 훨씬 늦게 풀린다.그것들은 NSObject -dealloc 호출된 object_dispose() 방법에서 방출될 것이다.

속성 삭제


대상 연결을 처음 접했을 때 objc_removeAssociatedObjects() 를 호출해서 삭제 작업을 시도할 수 있지만, 문서에서 말한 바와 같이 이 함수를 수동으로 호출해서는 안 된다.
이 함수의 주요 목적은 '초시 상태' 에서 대상을 쉽게 되돌려 주는 것이다.이 함수로 대상의 속성을 삭제해서는 안 된다. 왜냐하면 다른 고객이 추가한 속성도 제거될 수 있기 때문이다.규범화된 방법은 objc_setAssociatedObject 방법을 호출하고 nil 값을 보내서 연결을 제거하는 것입니다.

우수한 예


세부 사항을 더욱 잘 실현하기 위해 개인 속성을 추가합니다.내장 클래스를 확장할 때 추가 속성을 유지하는 상태가 필요할 수 있습니다.다음은 매우 교과서적인 관련 대상의 용례입니다.AFNetworking은 UIImageView의category에서 관련 대상을 사용하여operation 대상을 유지합니다. 인터넷의 어떤 URL에서 다른 단계로 그림을 가져오는 데 사용됩니다.
category 기능을 강화하기 위해public 속성을 추가합니다.어떤 경우 이런 (관련 대상을 통해) category 행동을 더욱 유연하게 하는 것은 변수를 가진 방법으로 실현하는 것보다 더 의미가 있다.이런 상황에서 관련 대상으로 대외 개방의 속성을 실현할 수 있다.지난AFNetworking의 예로 돌아가서 UIImageView category imageResponseSerializer 방법은 그림을 필터로 표시하거나 하드디스크에 캐시하기 전에 내용을 바꿀 수 있도록 합니다.
KVO에 대한 연관 관찰자를 만듭니다.하나의 category 구현에서 KVO를 사용할 때, 이 대상 자체가 관찰자가 아닌 사용자 정의 관련 대상을 사용하는 것을 권장합니다.ng an associated observer for KVO**. When using KVO in a category implementation, it is recommended that a custom associated-object be used as an observer, rather than the object observing itself.

반례


값이 필요하지 않을 때 관련 대상을 만듭니다.흔히 볼 수 있는 예는view에 모델의 속성, 값, 또는 다른 혼합된 데이터를 저장하는 편리한 방법을 만드는 것이다.만약 그 데이터가 이후에 전혀 쓰이지 않는다면 이런 방법은 별 문제가 없지만 대상에 연관된 방법을 쓰는 것은 바람직하지 않다.
하나의 값이 다른 값에 의해 추산될 수 있을 때 관련 대상을 만듭니다.예를 들어 cellForRowAtIndexPath:를 호출할 때view를 가리키는 UITableViewCell에accessoryview의 인용을 저장하여 tableView:accessoryButtonTappedForRowWithIndexPath:에 사용합니다.
X를 연관 객체로 대체합니다. 여기서 X는 다음 의미를 나타낼 수 있습니다.
계승이 원래의 클래스를 확장하는 것보다 편리할 때 하위 클래스를 사용합니다.
이벤트의 응답자에게 응답 동작을 추가합니다.
응답 동작을 사용하기 불편할 때 사용하는 제스처 동작 포착.
다른 대상에서 에이전트가 실행될 때 에이전트 (delegate) 를 사용해야 합니다.
NSNotification 및 NSNotification Center를 사용하여 시스템 전반에 걸친 이벤트 알림을 부드럽게 결합합니다.* * *

다른 문제 해결 방법에 비해 관련 대상은 최후의 선택으로 여겨져야 한다(사실category도 최선의 방법으로 여겨서는 안 된다).
다른 정교한 Trick, hack,workaround와 마찬가지로 보통 사람들은 공부를 마친 후에 장면을 찾아서 즐겨 사용한다.당신이 그것을 정확하게 사용할 때 그것이 발휘하는 역할을 이해하고 감상할 수 있는 모든 것을 다하는 동시에 이 해결 방법을 선택할 때, 경멸당하는 질문을 피해야 한다. "이것이 무슨 물건입니까?"어색하다.

좋은 웹페이지 즐겨찾기