대상이 회수될 때 Weak 포인터가 자동으로 nil로 설정되는 실현 원리
1. 앞말
우리는 Weak 포인터가 인용 대상의 계수를 증가시키지 않고 인용 대상이 회수될 때 자동으로
nil
로 설정되는 것을 알고 있다.일반적으로 순환 인용 문제를 해결하는 데 쓰인다.그렇다면 자동nil
내부는 어떻게 이루어졌을까?2. 내부 구현 - Weak 표
런타임은 대상을 가리키는 모든 위크 포인터를 저장하는 데 사용되는 위크 테이블을 유지합니다.Weak표는 사실 해시표입니다. Key는 대상의 주소를 가리키고,Value는 Weak포인터의 주소 (이 주소의 값은 대상의 주소를 가리킨다) 의 그룹입니다.
대상이 회수될 때 층층이 호출되면 다음 방법으로 모든 Weak 바늘의 값을
nil
로 설정합니다.(구체적으로 objc-weak.m에 정의됨)PRIVATE_EXTERN void
arr_clear_deallocating(weak_table_t *weak_table, id referent) {
{
weak_entry_t *entry = weak_entry_for_referent(weak_table, referent);
if (entry == NULL) {
/// XXX shouldn't happen, but does with mismatched CF/objc
//printf("XXX no entry for clear deallocating %p
", referent);
return;
}
// zero out references
for (int i = 0; i < entry->referrers.num_allocated; ++i) {
id *referrer = entry->referrers.refs[i].referrer;
if (referrer) {
if (*referrer == referent) {
*referrer = nil;
}
else if (*referrer) {
_objc_inform("__weak variable @ %p holds %p instead of %p
", referrer, *referrer, referent);
}
}
}
weak_entry_remove_no_lock(weak_table, entry);
weak_table->num_weak_refs--;
}
}
간단하게 말하자면, 이 방법은 우선 대상 주소에 따라 위크 포인터 주소의 그룹을 얻은 다음에 이 그룹을 옮겨다니며 그 중의 데이터를
nil
로 설정하고, 마지막으로 이entry를 위크 테이블에서 삭제한다.대상 회수 시 위크 바늘을 어떻게 설정하는지
nil
만 간단히 말하고, 위크 바늘을 위크 테이블에 어떻게 등록하는지, 어떻게 유지하는지는objc-위크를 참고할 수 있다.m의 다른 원본 코드입니다.이를 통해 알 수 있듯이 Weak 포인터의 사용은Hash표의 추가 삭제와 수정과 관련되어 일정한 성능 비용이 든다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.