5

내 질문은 NSObject 파생 된 개체에 대한 보유 개수를 구현하는 Foundation의 현재 버전 (또는 Objective-C 런타임 라이브러리가 여기에있는 것 같기 때문에)입니다. 내가 NSObject.mm에서 볼 수 있듯이 NSObject의 인터페이스 본문에 retain count이라는 이바가 없습니다. 대신, 각 개체에 대한 참조 카운터를 포함하는 일종의 테이블 또는 맵이있는 것으로 보입니다. 그러나 보유 카운트가 실제로지도로 수행 된 경우 및 release 연산이 너무 비싸지 않으므로 (이 경우에는 뮤텍스를 잠그고 잠금 해제해야하며,지도를 찾아 올바른 객체를 찾으십시오. 다중 스레드 환경에서 한 번에 하나의 객체 만 유지/해제 될 수 있다는 사실)?보유 수는 NSObject에서 어떻게 구현됩니까?

나는 새로운 객체를 할당 할 때, 어느 쪽도 ([NSObject alloc]에 의해 호출되는 함수를 것 같다) NSObject.mm에서 _objc_rootAllocWithZone에서 1로 유지 카운터를 설정 관련 내용을 찾지 못 하셨나요 objc-runtime-new.mm에서 _class_createInstanceFromZone (즉, 도착에 나중에 _objc_rootAllocWithZone에 의해 호출 됨).

+2

- (NSUInteger) retainCount {return rand()}; – CodaFi

+0

오, 세상에, 나는 종말을 잘못 놓았다; ... 나는 오늘 밤 자지 않을 것이다. – CodaFi

답변

10

NSObject의 보유 수는 실제로 글로벌지도에 보관됩니다. 실제로 IIRC는 잠금 경합을 줄이기 위해 객체의 주소를 기준으로 분할 된 맵 세트를 실제로 사용하지만 실제로 구현 세부 사항은 구현 세부 사항입니다.

어쨌든 보유 수가 1이 아니므로 보유 수를 1로 설정하는 코드를 찾을 수 없습니다. 보관 횟수가 1 인 개체는지도에 저장되지 않습니다. 객체는 최초의 1을 지나서 retain 일 때 보유 개수지도로만 입력됩니다. 이것은 보유 수 증가가 과거 1이 아닌 일반적인 객체의 속도를 높이는 최적화입니다.

+1

... 보유 카운트가 전혀없는 태그가 지정된 포인터의 특별한 경우가 있습니다. 데이터 자체는 포인터 내에서 인코딩되므로 기술적으로 참조로보다는 값으로 전달합니다 (참조가 값이고 참조 뒤에 아무 것도 없기 때문에). – Tommy

+0

참. 물론'-retain'과'-release'를 오버라이드 (override)하는 클래스는 자유롭게 retain count를 구현할 수 있습니다. 보유 수를 ivar로 포함시키는 많은 클래스가 있습니다. 왜냐하면 더 큰 오브젝트를 갖는 대신에'retain'과'release'를 빠르게하는 것을 선호하기 때문입니다. –

+0

확인. 그렇다면 왜 그들은 ivar를 카운터로 사용하지 않을 것인데, 이는 보유/해제 비용을 줄일 것입니까? 지도 사용에 대한 특별한 이유가 있는지 아십니까? – LuisABOL