2013-02-15 11 views
5

Moje pytanie brzmi, w jaki sposób bieżące wersje Foundation (lub biblioteki wykonawczej Objective-C, ponieważ wydaje się, że tam są) implementują liczbę zatrzymań dla obiektów pochodnych NSObject? Jak mogłem zobaczyć na NSObject.mm, nie ma ivar o nazwie retain count w ciele interfejsu NSObject. Zamiast tego wydaje się, że istnieje rodzaj tabeli lub mapy, która zawiera liczniki odwołań dla każdego obiektu. Ale jeśli licznik zatrzymań jest rzeczywiście wykonywany za pomocą mapy, nie są to operacje zbyt kosztowne w przypadku tego rodzaju implementacji (ponieważ w tym przypadku konieczne jest zablokowanie i odblokowanie muteksów, wyszukanie mapy w celu znalezienia odpowiedniego obiektu, oprócz fakt, że w środowisku wielowątkowym można zatrzymać/zwolnić tylko jeden obiekt na raz)?W jaki sposób przeliczana jest wartość NSObject?

Nie mogę znaleźć nic związanego z ustawieniem licznika zachowania do 1 przy przydzielaniu nowy obiekt, ani w _objc_rootAllocWithZone na NSObject.mm (co wydaje się być funkcja, która jest wywoływana przez [NSObject alloc]) ani w _class_createInstanceFromZone w objc-runtime-new.mm (który dostaje nazwany później przez _objc_rootAllocWithZone).

+2

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

+0

O, dobry Boże, źle przyjąłem zakończenie, ... Nie będę dziś spać. – CodaFi

Odpowiedz

10

Liczba zatrzymań dla NSObject jest rzeczywiście przechowywana na mapie globalnej. IIRC faktycznie korzysta z zestawu map, które są podzielone na partycje, prawdopodobnie na podstawie adresu obiektu, aby zmniejszyć rywalizację o blokadę, ale rzeczywiste szczegóły implementacji są właśnie tym, szczegóły implementacji.

W każdym razie nie można znaleźć kodu, który ustawi liczbę zatrzymań na 1, ponieważ nie ma żadnych. Obiekty z zatrzymaną liczbą 1 nie są umieszczane na mapie. Obiekty wprowadzają tylko mapę zliczania zatrzymania, gdy są retain po pierwszej 1. Jest to optymalizacja, która przyspiesza wspólny przypadek obiektów, które nigdy nie mają wzrostu liczby zatrzymań po 1.

+1

... ze specjalnym przypadkiem oznaczonych wskaźników, które w ogóle nie mają zliczenia. Same dane są zakodowane wewnątrz wskaźnika, więc technicznie przekazujesz je przez wartość, a nie przez odniesienie (ponieważ odniesienie jest wartością i za referencją nie ma nic rzeczywistego). – Tommy

+0

Prawda. I oczywiście każda klasa, która przesłania '-retain' i' -release', może mieć własną implementację licznika zatrzymania. Istnieje pewna liczba klas, które umieszczają liczbę zatrzymań jako ivar, ponieważ wolą przyspieszyć "zatrzymanie" i "zwolnienie" kosztem posiadania większego obiektu. –

+0

Ok. Ale dlaczego nie używają ivar jako licznika, który zmniejszyłby koszt utrzymania/zwolnienia? Czy wiesz, czy istnieje jakiś specjalny powód używania map? – LuisABOL

Powiązane problemy