iOS 소스 코드 읽 기 필수 지식의 Tagged Pointer
애플 이 Tagged Pointer 의 특징 에 대한 소개:
아이 폰 5s 는 64 비트 프로 세 서 를 사용한다.64 비트 프로그램 에 대해 우리 의 데이터 형식의 길 이 는 CPU 의 길이 와 관계 가 있다.
이렇게 하면 일부 대상 이 차지 하 는 메모리 가 배로 늘 어 날 것 이다.
또한 유지보수 프로그램의 대상 은 메모 리 를 분배 하고 인용 계 수 를 유지 하 며 생명 주 기 를 관리 해 야 하 며 사용 대상 은 프로그램의 운행 에 부담 을 준다.
Tagged Pointer
애플 은 위 에서 언급 한 메모리 사용량 과 효율 문 제 를 개선 하기 위해 Tagged Pointer 대상 을 제시 했다.NSNumber,NSDate 와 같은 변수 자체 의 값 이 사용 해 야 하 는 메모리 크기 는 8 개의 바이트 가 필요 하지 않 기 때문에 정수 로 볼 때 4 개의 바이트 가 표시 할 수 있 는 기호 정수 가 20 억 여 만 에 달 할 수 있 습 니 다(주:2^31=2147483648,다른 1 위 는 기호 위치 로).절대 다수의 상황 에서 처리 할 수 있 습 니 다.
우 리 는 한 대상 의 지침 을 두 부분 으로 나 누 어 일 부 는 데 이 터 를 직접 저장 하고 다른 일 부 는 특수 표시 로 서 이것 은 특별한 지침 이 며 어떠한 주 소 를 가리 키 지 않 는 다 는 것 을 표시 할 수 있다.그래서 Tagged Pointer 대상 을 도입 한 후 64 비트 CPU 에서 NSNumber 의 메모리 그림 은 다음 과 같 습 니 다.
Tagged Pointer
테스트
#import
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSNumber *number1 = @1;
NSNumber *number2 = @2;
NSNumber *number3 = @3;
NSNumber *numberFFFF = @(0xFFFF);
NSNumber *numberLager = @(MAXFLOAT);
NSLog(@"number1 pointer is %p", number1);
NSLog(@"number2 pointer is %p", number2);
NSLog(@"number3 pointer is %p", number3);
NSLog(@"numberLager pointer is %p", numberLager);
/*
2017-03-10 12:07:50.731726 TaggedPoint[1690:50438] number1 pointer is 0x127
2017-03-10 12:07:50.731992 TaggedPoint[1690:50438] number2 pointer is 0x227
2017-03-10 12:07:50.732011 TaggedPoint[1690:50438] number3 pointer is 0x327
2017-03-10 12:07:50.732043 TaggedPoint[1690:50438] numberLager pointer is 0x1002006a0
*/
}
return 0;
}
0x 127 을 예 로 들 어 tag 27(27 을 표시 로 가정)을 제거 하면 0x1 은 number 의 값 입 니 다.0x227
0x327
이런 규칙 이 있어 요.
numberLager 가 저장 하 는 값 은 MAXFloat 로 tagged pointer 가 저장 할 수 있 는 범 위 를 초과 한 것 이 분명 합 니 다.
그래서 인쇄 된 주 소 는 단순 한 포인터 주소 로 numberLager 를 저장 하 는 메모리 주 소 를 가리킨다.
isa 포인터 에 미 친 영향
tagged pointer 는 진정한 대상 이 아니 기 때문에 isa 포인터 로 컴 파일 할 때 오 류 를 보고 할 수 있 습 니 다.
그림:
우리 가 object 로 바 꾸 는 것 을 알려 줍 니 다.getClass()
object_getClass()에서 해당 하 는 처 리 를 했 습 니 다.
object 때문에getClass()는 대응 하 는 실현 이 없 으 며,다른 곳 에서 1,2 를 엿 볼 수 밖 에 없다.
objc-weak.mm
weak_read_no_lock(weak_table_t *weak_table, id *referrer_id)
{
objc_object **referrer = (objc_object **)referrer_id;
objc_object *referent = *referrer;
if (referent->isTaggedPointer()) return (id)referent;
//...
}
inline bool
objc_object::isTaggedPointer()
{
#if SUPPORT_TAGGED_POINTERS
return ((uintptr_t)this & TAG_MASK);
#else
return false;
#endif
}
여기 서 대상 의 값 을 취하 여 약간의 판단 을 하 였 다.tagged pointer 라면 대상 의 값 은 포인터 입 니 다.
tagged pointer 가 아니라면 대상 의 값 은 포인터 가 가리 키 는 메모리 영역 에 있 는 값 입 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swift의 패스트 패스Objective-C를 대체하기 위해 만들어졌지만 Xcode는 Objective-C 런타임 라이브러리를 사용하기 때문에 Swift와 함께 C, C++ 및 Objective-C를 컴파일할 수 있습니다. Xcode는 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.