Objective - C 의 meta - class 를 자세히 설명 합 니 다.
본문 제목: Objective - C 의 meta - class 는 무엇 입 니까?
원본 주소:http://www.cocoawithlove.com/2010/01/what-is-meta-class-in-objective-c.html
이 편 에 서 는 오 브 젝 티 브 - C 에서 상대 적 으로 낯 선 개념 인 meta - class 를 다룬다.OC 의 모든 종 류 는 이와 관련 된 meta class 가 있 지만 당신 은 거의 영원히 직접 사용 하지 않 을 것 입 니 다. 그들 은 항상 신비 로 운 베일 을 쓰 고 있 습 니 다.필 자 는 실행 할 때 동적 으로 class 를 만 드 는 것 을 인용 하여 만 든 class pair 를 분석 함으로써 meta - class 가 무엇 인지 알 고 OC 의 대상, 클래스 에 대한 의 미 를 더욱 깊이 이해 할 것 이다.
실행 중 클래스 만 들 기
다음 코드 가 실 행 될 때 NSError 의 하위 클래스 를 만 들 고 인 스 턴 스 방법 을 추가 합 니 다.
Class newClass =
objc_allocateClassPair([NSError class], "RuntimeErrorSubclass", 0);
class_addMethod(newClass, @selector(report), (IMP)ReportFunction, "v@:");
objc_registerClassPair(newClass);
함수 ReportFunction 은 추 가 된 인 스 턴 스 방법의 구체 적 인 실현 입 니 다. 다음 과 같 습 니 다.
void ReportFunction(id self, SEL _cmd)
{
NSLog(@"This object is %p.",self);
NSLog(@"Class is %@, and super is %@.",[self class],[self superclass]);
Class currentClass = [self class];
for( int i = 1; i < 5; ++i )
{
NSLog(@"Following the isa pointer %d times gives %p",i,currentClass);
currentClass = object_getClass(currentClass);
}
NSLog(@"NSObject's class is %p", [NSObject class]);
NSLog(@"NSObject's meta class is %p",object_getClass([NSObject class]));
}
모든 것 이 간단 해 보 입 니 다. 실행 할 때 클래스 를 만 드 는 데 세 단계 만 필요 합 니 다. 1. "class pair" 에 공간 을 할당 합 니 다 (obbc allocateClassPair 사용). 2. 만 든 클래스 에 방법 과 구성원 을 추가 합 니 다.
3. 만 든 이 종 류 를 등록 하여 사용 할 수 있 도록 합 니 다 (obbc registerClassPair 사용).
독자 들 은 곧 "class pair" 가 무엇 입 니까? obbc allocateClassPair 는 하나의 값 만 되 돌려 줍 니 다: Class. 그러면 pair 의 반쪽 은 어디 에 있 습 니까?
예, 이 반쪽 이 meta - class, 즉 이 짧 은 글 의 제목 임 을 알 고 있 을 것 입 니 다. 하지만 그것 이 무엇 인지, 왜 필요 한 지, OC 의 대상 과 클래스 의 관련 배경 을 설명해 야 합 니 다.
하나의 데이터 구 조 는 어떻게 하나의 대상 이 됩 니까?
모든 대상 에 속 하 는 클래스 가 있 습 니 다. 이것 은 대상 을 대상 으로 하 는 기본 개념 이지 만 OC 에 서 는 모든 데이터 구조 에 효과 가 있 습 니 다. 모든 데이터 구 조 는 적당 한 위치 에서 하나의 클 라 스 를 가리 키 는 포인터 만 있 으 면 하나의 대상 으로 여 겨 질 수 있 습 니 다. OC 에 서 는 한 대상 이 어떤 클래스 에 속 하 는 지, 그것 의 isa 포인터 가 가리 키 는 것 입 니 다. 이 isa 는포인터 가 이 대상 이 속 한 클 라 스 를 가리 키 고 있 습 니 다.
실제로 OC 에서 대상 의 정 의 는 다음 과 같다.
typedef struct objc_object {
Class isa;
}*id;
이 정 의 는 Class 를 가리 키 는 모든 지침 을 첫 번 째 구성원 으로 하 는 데이터 구 조 는 obsc object 로 여 겨 질 수 있 음 을 나타 낸다.
가장 중요 한 특징 은 OC 의 모든 대상 에 게 메 시 지 를 보 낼 수 있다 는 것 이다. 다음 과 같다.
【@”stringValue" writeToFile:@"/file.txt atomically:YES encoding: NSUTF8StringEncoding error:NULL];
실행 원 리 는 OC 대상 에 게 메 시 지 를 보 낼 때 (위의 @ "stringValue") 실행 시 라 이브 러 리 는 대상 의 isa 포인터 에 따라 이 대상 이 속 한 종 류 를 찾 는 것 입 니 다.(위의 예 를 들 어 NSCFString 클래스 를 찾 을 수 있 습 니 다). 이 클래스 는 부모 클래스 의 인 스 턴 스 방법 을 찾 을 수 있 도록 모든 인 스 턴 스 방법의 목록 과 슈퍼 클 라 스 를 가리 키 는 지침 을 포함 합 니 다. 런 타임 라 이브 러 리 는 클래스 의 방법 목록 과 부모 클래스 의 방법 목록 에서 이 selector 에 맞 는 것 을 찾 습 니 다. (위의 예 를 들 어 이 selector 는 "writeToFile: atomically: encoding: error" 입 니 다)방법 입 니 다. 찾 으 면 이 방법 을 실행 합 니 다. 관건 은 대상 에 게 보 낸 메 시 지 를 정의 하 는 것 입 니 다.
meta - class 가 무엇 입 니까?
이로써 OC 클래스 도 하나의 대상 이라는 것 을 알 수 있 습 니 다. 한 클래스 에 메 시 지 를 보 낼 수 있다 는 뜻 입 니 다. NSStringEncoding defaultStringEncoding = [NSString defaultStringEncoding]; 이 예 에서 defaultStringEncoding 은 NSString 클래스 에 전 송 됩 니 다. OC 클래스 자체 도 하나의 대상 이기 때 문 입 니 다. 즉, Class 의 데이터 구 조 는 반드시 isa 포인터 로 시 작 됩 니 다. 바 이 너 리 단계 에서 obsc object 와 완전히 호 환 됩 니 다. 다음 클래스 구조의 다음 필드 는 슈퍼 class 를 가리 키 는 포인터 일 것 입 니 다.(또는 nil 을 가리 키 며, 기본 클래스 에 대해 서 는). 하나의 클래스 를 어떻게 정의 하 는 지 는 여러 가지 방법 이 있 습 니 다. 실행 중인 라 이브 러 리 버 전에 의존 하지만, 어떤 방법 이 든 지 간 에 그들 은 하나의 isa 를 첫 번 째 필드 로 하고, 그 다음은 슈퍼 클 라 스 필드 입 니 다.
typedef struct objc_class *Class;
struct objc_class{
Class isa;
Class super_class;
/*followed by runtime specific details...*/
};
클래스 방법 을 호출 할 수 있 도록, 이러한 종류의 isa 지침 은 이러한 방법 을 포함 하 는 클래스 구조 체 를 가 리 켜 야 합 니 다. 이렇게 하면 meta - class 의 개념 을 가 져 옵 니 다. meta - class 는 클래스 대상 의 클래스 입 니 다. 간단하게 설명 하 겠 습 니 다. 대상 에 게 메 시 지 를 보 낼 때 runtime 은 이 대상 이 속 한 방법 목록 에서 찾 습 니 다. 하나의 클래스 에 메 시 지 를 보 낼 때 runtime 은 이러한 meta - class 의 방법 목록 에서 찾 습 니 다. meta - class 가 중요 한 이 유 는 하나의 클래스 의 모든 방법 이 저장 되 어 있 기 때 문 입 니 다. 클래스 마다 하나의 meta - class 가 있 습 니 다. 클래스 마다 방법 기반 이 완전히 같 을 수 없 기 때 문 입 니 다.
meta - class 의 종 류 는 무엇 입 니까?
meta - class 는 Class 와 마찬가지 로 하나의 대상 입 니 다. 메시지 호출 함 수 를 보 낼 수 있 습 니 다. 자 연 스 럽 게 meta - class 에 도 isa 포인터 가 있 습 니 다. 모든 meta - class 는 기본 클래스 의 meta - class 를 소속 클래스 로 사용 합 니 다. 구체 적 으로 모든 NSObject 계승 시스템 의 meta - class 는 NSObject 의 meta - class 를 자신 이 속 한 것 으로 사용 합 니 다.클래스. 이 규칙 에 따라 모든 meta - class 는 기본 클래스 의 meta - class 를 클래스 로 사용 합 니 다. 기본 클래스 의 meta - class 도 자신 에 게 속 합 니 다. 즉, 기본 클래스 의 meta - class 의 isa 지침 은 자신 을 가리 키 는 것 입 니 다.
클래스 와 meta - class 의 계승
하나의 클래스 가 슈퍼 클래스 포인터 로 자신의 부모 클래스 를 가리 키 는 것 처럼 meta - class 의 슈퍼 클래스 는 클래스 의 슈퍼 클래스 의 meta - class 를 가리킨다. 기본 클래스 의 meta - class 까지 거 슬러 올 라 가면 슈퍼 클래스 는 기본 클래스 자신 을 가리킨다.이렇게 되면 전체 상속 시스템 의 인 스 턴 스, 클래스, meta - class 는 상속 시스템 의 기본 클래스 에서 파생 됩 니 다. NSObject 상속 시스템 에 있어 서 NSObject 의 인 스 턴 스 방법 은 시스템 의 모든 인 스 턴 스, 클래스 와 meta - class 에 효과 적 입 니 다. NSObject 의 클래스 방법 은 시스템 의 모든 클래스 와 meta - class 에 효과 적 입 니 다. 문자 로 설명 하면 항상 유효 합 니 다.헷 갈 리 게 하 는 Greg Parker 는 이러한 관 계 를 보 여 주 는 멋 진 그래프 를 제시 했다. 링크 를 열 려 면 클릭 하 세 요.
실험 증명:
이 함수 의 목적 은 isa 지침 을 따라 인쇄 하 는 것 입 니 다. ErportFunction 을 실행 하기 위해 서 는 인 스 턴 스 를 만 들 고 report 방법 을 사용 해 야 합 니 다.id instanceOfNewClass = [[newClass alloc]initWithDomain:@"some Domain" code:0 userInfo:nil];
[instanceOfNewClass performSelector:@"report)];
[instanceOfNewClass release];
리 포트 방법 에 대해 설명 을 하지 않 았 기 때문에 컴 파 일 러 경 고 를 피하 기 위해 performSelector 를 사용 합 니 다.
그리고 Report Function 함 수 는 isa 를 따라 검색 하여 class, meta - class, meta - class 의 class 가 어떤 상황 인지 알려 줍 니 다.
【 비고: ReportFunction 은 object getClass 를 사용 하여 isa 포인터 가 가리 키 는 종 류 를 가 져 옵 니 다. isa 포인 터 는 보 호 받 는 구성원 이기 때문에 다른 대상 의 isa 포인 터 를 직접 방문 할 수 없습니다. ReportFunction 은 class 방법 을 사용 하지 않 았 습 니 다. 이 방법 을 사용 하지 않 은 것 은 meta - class 를 가 져 올 수 없 기 때 문 입 니 다. 이 종 류 를 되 돌 릴 뿐 입 니 다. (따라서 [NSString class]NSString 의 meta - class 가 아 닌 NSString 클래스 로 돌아 갑 니 다.]
다음은 프로그램의 출력 입 니 다.
This object is 0x10010c810.
Class is RuntimeErrorSubclass, and super is NSError.
Followingthe isa pointer 1times gives 0x10010c600
Followingthe isa pointer 2times gives 0x10010c630
Followingthe isa pointer 3times gives 0x7fff71038480
Followingthe isa pointer 4times gives 0x7fff71038480
NSObject's class is 0x7fff710384a8
NSObject's meta class is 0x7fff71038480
isa 를 통 해 얻 은 주소 관찰: 대상 의 주 소 는? 0x10010c 810. 클래스 의 주 소 는? 0x10010c 600. 클래스 의 meta - class 주 소 는? 0x10010c 630. 클래스 의 meta - class 클래스 주 소 는? 0x7fff 71038480. (즉 NSOjbect 의 meta - class) NSObject 의 meta - class 클래스 주 소 는 그 자체 입 니 다. 이 주소 들 의 값 은 중요 하지 않 습 니 다. 중요 한 것 은 meta - class 에서 NSObject 까지 의 meta - class 의 전체 절 차 를 설명 하 는 것 입 니 다.
결론:
meta - class 는 클래스 대상 의 클래스 입 니 다. 클래스 마다 자신 만 의 meta - class 가 있 습 니 다. 모든 클래스 대상 은 같은 meta - class 에 속 하지 않 습 니 다. meta - class 는 클래스 대상 이 계승 시스템 의 기본 클래스 의 모든 인 스 턴 스 와 클래스 방법, 그리고 계승 시스템 의 모든 중간 클래스 방법 을 가지 고 있 음 을 보증 합 니 다. 모든 NSObject 계승 시스템 의 클래스, NSObject 의 인 스 턴 스 방법 과 프로 토 콜 방법 에 대해 서 는그들 과 그들의 meta - class 대상 은 모두 유효 해 야 합 니 다. 모든 meta - class 는 기본 클래스 의 meta - class 를 자신의 기본 클래스 로 사용 합 니 다. 최상 위 클래스 의 meta - class 도 마찬가지 입 니 다. 자신 을 가리 키 는 것 일 뿐 입 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.