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
'source' 카테고리의 다른 글
Rest Controller에서 메서드 Cors 문제 삭제 (0) | 2023.07.30 |
---|---|
Spring Bean 범위: 세션 및 글로벌 세션 (0) | 2023.07.30 |
matplotlib를 사용하여 SQL(MariaDB)의 표 값 표시 (0) | 2023.07.30 |
MockMVC를 사용한 통합 테스트 스프링 부트 (0) | 2023.07.30 |
최적화를 통해 손상된 인덱스이지만 검사 또는 분석을 통해 손상되지 않음 (0) | 2023.07.30 |