source

objc_set Associated Object()란 무엇이며 어떤 경우에 사용해야 합니까?

manycodes 2023. 7. 30. 17:57
반응형

objc_set Associated Object()란 무엇이며 어떤 경우에 사용해야 합니까?

제가 맡은 프로젝트에서 원래 작성자가 사용하기로 선택했습니다.objc_setAssociatedObject()그게 무엇을 하는지, 왜 그들이 그것을 사용하기로 결정했는지 100% 확실하지 않습니다.

저는 그것을 찾아보기로 결정했고, 안타깝게도, 문서들은 그것의 목적에 대해 그리 설명적이지 않습니다.

AssociatedObjectobjc_set 파일
지정된 키 및 연결 정책을 사용하여 지정된 개체에 대한 연결 값을 설정합니다.
void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)

object
연결의 원본 개체입니다.
key
연결 키입니다.
value
개체의 키 키와 연결할 값입니다.기존 연결을 지우려면 nil을 전달합니다.
policy
연결에 대한 정책입니다.가능한 값은 "관련 개체 동작"을 참조하십시오.

그렇다면 이 기능은 정확히 무엇을 하고 어떤 경우에 사용되어야 할까요?


답변을 읽은 후 편집

그렇다면 다음 코드의 요점은 무엇입니까?

Device *device = [self.list objectAtIndex:[indexPath row]];
DeviceViewController *next = [[DeviceViewController alloc] initWithController:self.controller
                                                                            device:device
                                                                               item:self.rootVC.selectedItem];  
    objc_setAssociatedObject(device, &kDeviceControllerKey, next, OBJC_ASSOCIATION_RETAIN);

디바이스가 이미 인스턴스 변수인 경우 디바이스를 뷰 컨트롤러와 연결하는 이유는 무엇입니까?

objc_setAssociatedObject키 값 저장소를 각 Objective-C 개체에 추가합니다.인스턴스 변수에 반영되지 않고 개체에 대한 추가 상태를 저장할 수 있습니다.

메인 구현 외부의 객체에 속하는 것을 저장하고 싶을 때 매우 편리합니다.주요 사용 사례 중 하나는 인스턴스 변수를 추가할 수 없는 범주입니다.서 당신은 는위하치를 합니다.objc_setAssociatedObject를 추변를 니다첨합에 합니다.self물건.

올바른 연결 정책을 사용하는 경우 기본 개체의 할당이 해제되면 개체가 해제됩니다.

Objective-C 런타임 참조에 대한 참조 문서:

런타임 함수 Objective-C를 합니다.objc_setAssociatedObject한 개체와 다른 개체를 연결합니다.이 함수에는 소스 개체, 키, 값 및 연결 정책 상수의 네 가지 매개 변수가 사용됩니다.키는 빈 포인터입니다.

  • 각 연결의 키는 고유해야 합니다.일반적인 패턴은 정적 변수를 사용하는 것입니다.
  • 은 연결된 합니다.
    "" " " " " "의 .
    관성은원로만으들거나지연어자적,나,
    원자론적으로이 패턴은

    재산 ("" 참조
    선언 속성").합니다( ).
    및 objc_provider 파일
    연관 개체 동작).

배열과 문자열 간의 연결 설정

static char overviewKey;



NSArray *array =

    [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil];

// For the purposes of illustration, use initWithFormat: to ensure

// the string can be deallocated

NSString *overview =

    [[NSString alloc] initWithFormat:@"%@", @"First three numbers"];



objc_setAssociatedObject (

    array,

    &overviewKey,

    overview,

    OBJC_ASSOCIATION_RETAIN

);



[overview release];

// (1) overview valid

[array release];

// (2) overview invalid

OBJC_Association_RETain 정책은 어레이가 연결된 개체를 유지하도록 지정하므로 1에서 문자열 개요는 여전히 유효합니다.그러나 어레이가 할당 취소되면(지점 2) 개요가 릴리스되므로 이 경우에도 할당 취소됩니다.예를 들어 개요 값을 기록하려고 하면 런타임 예외가 생성됩니다.

다음은 개체 연결의 사용 사례 목록입니다.

하나: 인스턴스(instance) 변수를 범주에 추가합니다.일반적으로 이 기술은 사용하지 않는 것이 좋습니다. 하지만 여기 합법적인 사용의 가 있습니다.수정할 수 없는 개체에 대해 추가 인스턴스 변수를 시뮬레이션하려고 한다고 가정합니다(예: 하위 분류 없이 개체 자체를 수정하는 것).UI 이미지에 제목을 설정합니다.

// UIImage-Title.h:
@interface UIImage(Title)
@property(nonatomic, copy) NSString *title;
@end 

// UIImage-Title.m:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>

static char titleKey;

@implementation UIImage(Title)
- (NSString *)title
{
    return objc_getAssociatedObject(self, &titleKey);
}

- (void)setTitle:(NSString *)title
{
    objc_setAssociatedObject(self, &titleKey, title, OBJC_ASSOCIATION_COPY);
}
@end

또한 범주와 관련된 개체를 사용하는 매우 복잡한(하지만 멋진) 방법이 있습니다.기본적으로 선택기 대신 블록을 통과할 수 있습니다.UIControl.


번째: KVO와 함께 인스턴스 변수에 포함되지 않은 객체에 상태 정보를 동적으로 추가합니다.

이 개념은 객체가 런타임 동안(즉, 동적으로) 상태 정보만 얻는다는 것입니다.이 아이디어는 이 상태 정보를 인스턴스 변수에 저장할 수는 있지만 런타임에 인스턴스화된 개체에 이 정보를 연결하고 다른 개체와 동적으로 연결하는 것은 개체의 동적 상태라는 사실을 강조하는 것입니다.

이것을 보여주는 한 가지 좋은 예는 KVO 알림과 관련된 객체가 사용되는 라이브러리입니다.다음은 코드 발췌입니다(참고: 이 KVO 알림은 해당 라이브러리의 코드 작동을 실행하는 데 필요하지 않습니다.작성자가 편의를 위해 배치한 것으로, 기본적으로 이에 등록된 모든 개체는 KBO를 통해 변경 사항이 발생했음을 알립니다.)

static char BOOLRevealing;

- (BOOL)isRevealing
{
    return [(NSNumber*)objc_getAssociatedObject(self, &BOOLRevealing) boolValue];
} 

- (void)_setRevealing:(BOOL)revealing
{
    [self willChangeValueForKey:@"isRevealing"];
    objc_setAssociatedObject(self, &BOOLRevealing, 
       [NSNumber numberWithBool:revealing], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    [self didChangeValueForKey:@"isRevealing"];
}

보너스: 중요한 AF 네트워킹 라이브러리의 저자인 Matt Thompson의 관련 개체에 대한 이 토론/설명을 살펴 보십시오.

수정된 질문에 답변하기

디바이스가 이미 인스턴스 변수인 경우 디바이스를 뷰 컨트롤러와 연결하는 이유는 무엇입니까?

이 작업을 수행하려는 몇 가지 이유가 있습니다.

  • Device 클래스에 컨트롤러 인스턴스 변수 또는 속성이 없으며 이를 변경하거나 하위 분류할 수 없습니다(예: 소스 코드가 없는 경우).
  • 장치 개체와 연결된 두 개의 컨트롤러를 사용하려는 경우 장치 클래스를 변경하거나 하위 클래스로 분류할 수 없습니다.

개인적으로 낮은 수준의 Objective-C 런타임 기능을 사용할 필요가 있는 경우는 매우 드물다고 생각합니다.이건 제가 보기엔 코드 냄새 같은데요.

언급URL : https://stackoverflow.com/questions/5909412/what-is-objc-setassociatedobject-and-in-what-cases-should-it-be-used

반응형