Objective - C 의 meta - class 를 자세히 설명 합 니 다.

비교적 간단 한 영어 한 편, 중점 은 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 도 마찬가지 입 니 다. 자신 을 가리 키 는 것 일 뿐 입 니 다.

좋은 웹페이지 즐겨찾기