You are on page 1of 617

Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


• Kup książkę • Księgarnia internetowa
• Poleć książkę • Lubię to! » Nasza społeczność
• Oceń książkę
Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


Spis treci

O autorze ..........................................................................9
Podzikowania ...............................................................11
Wprowadzenie ...............................................................13
Rozdzia 1. Filozofia Objective-C .....................................................15
Model obiektowy ................................................................................... 15
Opowie o dwóch systemach typów .................................................... 17
C to Objective-C .................................................................................... 17
Jzyk i biblioteka ................................................................................... 18
Historia Objective-C .............................................................................. 20
Wieloplatformowo ............................................................................. 22
Kompilowanie programów napisanych w Objective-C ......................... 23

Rozdzia 2. Elementarz Objective-C ................................................25


Deklarowanie typów w Objective-C ..................................................... 26
Wysyanie wiadomoci .......................................................................... 28
Selektory ............................................................................................... 30
Deklarowanie klas ................................................................................. 31
Protokoy ............................................................................................... 35
Dodawanie metod do istniejcej klasy ................................................... 36
Nieformalne protokoy .......................................................................... 38
Generowanie metod przy uyciu zadeklarowanych waciwoci .......... 38
Sowa kluczowe self, _cmd i super ........................................................ 42
Wskanik isa ......................................................................................... 44
Inicjalizowanie klas ............................................................................... 46
Kodowanie typów .................................................................................. 47
Uywanie bloków .................................................................................. 49

Kup książkę Poleć książkę


4 Spis treci

Rozdzia 3. Zarzdzanie pamici ..................................................51


Zajmowanie i zwalnianie pamici ......................................................... 51
Przypisywanie do zmiennych instancyjnych ......................................... 52
Automatyczne zliczanie referencji ........................................................ 53
Zwracanie obiektów przez argumenty bdce wskanikami ................. 54
Unikanie cykli pozyskanych referencji .................................................. 56
Migracja do ARC .................................................................................. 57
Pule automatycznego zwalniania pamici ............................................. 59
Konstruktory automatycznie zwalniajce pami .................................. 61
Automatyczne zwalnianie obiektów w akcesorach ............................... 61
Wsparcie dla automatycznego odmiecania kolekcji ............................. 62
Wspópraca z C ..................................................................................... 64
Niszczenie obiektów .............................................................................. 65
Sabe referencje ..................................................................................... 66
Alokowanie skanowanej pamici .......................................................... 68

Rozdzia 4. Najwaniejsze wzorce w Objective-C .........................71


Dwufazowe tworzenie obiektów ........................................................... 71
Kopiowanie obiektów ............................................................................ 72
Archiwizowanie obiektów ..................................................................... 74
Tworzenie wyznaczonych inicjalizatorów ............................................. 76
Singleton ............................................................................................... 77
Delegowanie .......................................................................................... 79
Budowanie fasad ................................................................................... 80
Tworzenie klastrów klas ........................................................................ 81
Ptla wykonania .................................................................................... 83

Rozdzia 5. Liczby ..............................................................................85


Przechowywanie liczb w kolekcjach ..................................................... 86
Arytmetyka liczb dziesitnych .............................................................. 88
Konwersje midzy cigami znakowymi i liczbami ............................... 90
Odczytywanie liczb z cigów znakowych ............................................. 91

Rozdzia 6. Operacje na cigach znakowych ...............................93


Tworzenie staych cigów znakowych .................................................. 94
Porównywanie cigów znakowych ........................................................ 94
Przetwarzanie cigu znakowego litera po literze ................................... 96
Zmiana kodowania cigów znakowych ................................................. 98
Przycinanie cigów znakowych ........................................................... 100
Dzielenie cigów znakowych .............................................................. 101
Kopiowanie cigów znakowych .......................................................... 101
Tworzenie cigów znakowych z szablonów ........................................ 103
Dopasowywanie wzorców do cigów znakowych ............................... 105
Przechowywanie tekstu z formatowaniem ........................................... 106

Kup książkę Poleć książkę


Spis treci 5

Rozdzia 7. Kolekcje ........................................................................109


Uywanie tablic ................................................................................... 110
Kontrolowanie indeksów ..................................................................... 111
Przechowywanie nieuporzdkowanych grup obiektów ....................... 112
Tworzenie sownika ............................................................................ 113
Iterowanie po kolekcji ......................................................................... 114
Wyszukiwanie obiektu w kolekcji ....................................................... 116
Dziedziczenie z kolekcji ...................................................................... 118
Przechowywanie obiektów Objective-C w kolekcjach C++ ................ 120

Rozdzia 8. Data i czas ....................................................................123


Odczytywanie aktualnej daty ............................................................... 123
Przygotowanie dat do wywietlenia .................................................... 124
Zliczanie upywajcego czasu ............................................................. 126
Odczytywanie dat z cigów znakowych .............................................. 126
Zdarzenia stopera ................................................................................ 127

Rozdzia 9. Listy waciwoci ..........................................................129


Przechowywanie kolekcji w listach waciwoci ................................. 130
Odczytywanie danych z listy waciwoci ........................................... 131
Zmiana formatu list waciwoci ......................................................... 133
JSON ................................................................................................... 134
Przechowywanie ustawie ................................................................... 135
Przechowywanie dowolnych obiektów w systemie ustawie .............. 138

Rozdzia 10. Interakcja ze rodowiskiem ........................................141


Pobieranie wartoci rodowiskowych .................................................. 141
Przetwarzanie argumentów z linii komend .......................................... 142
Ustawienia regionalne uytkownika .................................................... 144
Nage zako czenie programu .............................................................. 145

Rozdzia 11. Kodowanie klucz-warto ..........................................147


Dostp do wartoci poprzez klucz ....................................................... 147
Uzyskiwanie zgodnoci z KVC ........................................................... 148

cieki do klucza ................................................................................. 151
Obserwowanie kluczy ......................................................................... 152
Uzyskiwanie zgodnoci z KVO ........................................................... 153

Rozdzia 12. Obsuga bdów ..........................................................155


Rónice w implementacji wyjtków .................................................... 156
Rzucanie i apanie wyjtków ............................................................... 157
Obiekty wyjtków ............................................................................... 159
Zunifikowany model wyjtków ........................................................... 160
Wyjtki a zarzdzanie pamici .......................................................... 161
Przekazywanie delegat z bdami ........................................................ 162
Zwracanie informacji o bdzie ........................................................... 163
NSError ............................................................................................... 164

Kup książkę Poleć książkę


6 Spis treci

Rozdzia 13. Dostp do katalogów i plików ....................................167


Odczytywanie pliku ............................................................................. 167
Przenoszenie i kopiowanie plików ...................................................... 169
Pobieranie atrybutów pliku .................................................................. 170
Modyfikacja cieek ............................................................................ 171
Sprawdzanie, czy plik lub katalog istnieje ........................................... 172
Praca z pakietami ................................................................................. 173
Odszukiwanie plików w lokacjach systemowych ................................ 175

Rozdzia 14. Wtki .............................................................................179


Tworzenie wtków .............................................................................. 179
Ustawianie priorytetu wtku ................................................................ 180
Synchronizowanie wtków .................................................................. 182
Przechowywanie danych specyficznych dla danego wtku ................. 183
Oczekiwanie na prawdziwo warunku ............................................... 185

Rozdzia 15. Bloki i Grand Central ...................................................189


Wizanie zmiennych z blokami ........................................................... 189
Zarzdzanie pamici a bloki .............................................................. 192
Wykonywanie czynnoci w tle ............................................................ 194
Tworzenie wasnych kolejek pracy ..................................................... 196

Rozdzia 16. Powiadomienia ............................................................199


danie powiadomie ......................................................................... 199
Wysyanie powiadomie ..................................................................... 201
Kolejkowanie powiadomie ................................................................ 201
Przesyanie powiadomie midzy aplikacjami .................................... 202

Rozdzia 17. Sie ................................................................................205


Wykorzystywanie obudowanych socketów z jzyka C ....................... 205
czenie si z serwerami ..................................................................... 207
Przesyanie obiektów przez sie .......................................................... 208
Wyszukiwanie wzów równolegych ................................................. 210
Wczytywanie danych spod adresu URL .............................................. 212

Rozdzia 18. Debugowanie Objective-C ........................................215


Inspekcja obiektów .............................................................................. 215
Rozpoznawanie problemów z pamici .............................................. 217
Obserwowanie wyjtków .................................................................... 218
Asercje ................................................................................................. 220
Zapisywanie wiadomoci o bdach .................................................... 221

Kup książkę Poleć książkę


Spis treci 7

Rozdzia 19. rodowisko uruchomieniowe Objective-C ...............223


Wysyanie wiadomoci na podstawie nazwy ....................................... 223
Odszukiwanie klas wedug nazwy ....................................................... 224
Sprawdzanie, czy obiekt posiada dan metod .................................... 225
Przekierowywanie wiadomoci ........................................................... 227
Odszukiwanie klas ............................................................................... 228
Inspekcja klas ...................................................................................... 229
Tworzenie nowych klas ....................................................................... 231
Dodawanie nowych zmiennych instancyjnych .................................... 232

Skorowidz ......................................................................235

Kup książkę Poleć książkę


8 Spis treci

Kup książkę Poleć książkę


Rozdzia 3.
Zarzdzanie pamici

Jeli pochodzisz ze rodowiska programistów C lub C++, prawdopodobnie we krwi


masz ledzenie wasnoci obiektów oraz rczne alokowanie ich i niszczenie. Jeli
pochodzisz ze rodowiska programistów jzyków podobnych do Javy, przywy-
ke do automatycznego odmiecacza pamici, który wykonuje t prac za Ciebie.
Objective-C na poziomie jzyka nie pozwala na alokacj lub dealokacj obiek-
tów. Jest to pozostawione kodowi napisanemu w C. Alokacja obiektów nastpuje
zwykle po wysaniu do ich klasy wiadomoci +alloc, która z kolei wywouje metod
malloc() lub podobn, by zarezerwowa pami na obiekt. Wysanie obiektowi wia-
domoci –dealloc czyci i usuwa jego zmienne instancyjne.
Framework Foundation rozbudowuje to proste, rczne zarzdzanie pamici o zlicza-
nie referencji. Gdy tylko zrozumiesz, jak dziaa, Twoje ycie stanie si prostsze.
Nowsze kompilatory pomog Ci, zdejmujc z Ciebie trud pisania kodu zliczajcego
referencje.

Zajmowanie i zwalnianie pamici


6 NSArray *anArray = [NSArray array];
7 anArray = [[NSArray alloc] init];
8 [anArray release];

Z pliku: retainRelease.m

Z kadym obiektem dziedziczcym z NSObject jest powizany licznik referencji.


Gdy osignie warto 0, obiekt jest niszczony. Obiekt utworzony przy uyciu
+alloc lub podobnej metody, jak np. +new czy +allocWithZone:, rozpoczyna swój
ywot z licznikiem ustawionym na warto jeden.

Kup książkę Poleć książkę


52 Rozdzia 3 ‹ Zarzdzanie pamici

Licznik referencji obiektu mona kontrolowa, wysyajc mu wiadomoci –retain


i -release. Jak wskazuj ich nazwy, wykorzystuje si je do pozyskiwania referencji
na obiekt lub jej zwalniania. Wiadomo –retain inkrementuje licznik referencji,
a wiadomo –release go dekrementuje.
By okreli obecny stan licznika referencji, wylij wiadomo –retainCount. Kuszce
moe by optymalizowanie kodu, polegajce na wykorzystaniu specjalnego przy-
padku, gdy istnieje tylko jedna referencja na obiekt. Jest to bardzo zy pomys.
Jak sama nazwa wskazuje, metoda zwraca liczb jawnie pozyskanych referencji,
a nie referencji w ogóle. Podczas tworzenia na stosie wskanika do obiektu po-
wszechne jest niezawracanie sobie gowy wysyaniem do niego wiadomoci –retain.
W efekcie do obiektu mog prowadzi dwie lub wicej referencji, cho licznik
jest ustawiony na jeden.
Wskaniki w Objective-C s podzielone na dwie kategorie: referencje wasno-
ciowe i referencje niewasnociowe. Referencja wasnociowa to taka, która
modyfikuje licznik referencji obiektu. Wywoujc metody takie jak +new lub –retain,
otrzymuje si referencj wasnociow do nowego obiektu. Wikszo pozosta-
ych metod zwraca referencje niewasnociowe. Zmienne instancyjne i globalne
s przewanie wskanikami wasnociowymi, wic powinno si im przypisa re-
ferencje wasnociowe. Trzeba take upewni si, e przed przypisaniem nowej
referencji wasnociowej usunito star (wysyajc wiadomo –release).
Zmienne tymczasowe s zwykle referencjami niewasnociowymi. Automatyczne
zliczanie referencji i odmiecanie pamici, którym przyjrzymy si w dalszej czci
obecnego rozdziau, wprowadzaj specjalne rodzaje tego typu referencji.

Przypisywanie do zmiennych instancyjnych


26 - (void)setStringValue: (NSString*)aString
27 {
28 id tmp = [aString retain];
29 [string release];
30 string = tmp;
31 }

Z pliku: ivar.m

Jest kilka rzeczy, na które trzeba uwaa podczas korzystania ze zliczania referencji.
Rozwamy tak oto prost metod ustawiajc:

Kup książkę Poleć książkę


Automatyczne zliczanie referencji 53

14 - (void)setStringValue: (NSString*)aString
15 {
16 [string release];
17 string = [aString retain];
18 }

Z pliku: ivar.m

Kod wyglda rozsdnie. Zwalniana jest referencja do starej wartoci, po czym pozy-
skiwana i przypisywana jest nowa warto. Zwykle kod bdzie dziaa, ale w kilku
przypadkach zawiedzie. Czyni to debugowanie go zajciem niezwykle trudnym.
Co stanie si, jeli warto aString i string bd takie same? W tym przypadku
wylesz jednemu obiektowi wiadomo –release, a nastpnie –retain. O ile inny
kod utrzyma referencj do obiektu, wszystko zadziaa poprawnie, ale jeli nie, to
pierwsza wiadomo spowoduje zniszczenie obiektu, a druga zostanie wysana do
„wiszcego” wskanika.
Na pocztku rozdziau pokazano lepsz implementacj, która najpierw pozyskuje
referencj do nowego obiektu. Zwró uwag, e powiniene zachowa warto
zwracan z wiadomoci –retain, bo niektóre obiekty zwróc inny obiekt, gdy je
pozyskasz. To bardzo rzadkie zachowanie, ale wystpuje raz na jaki czas.
W ko cu metoda nie jest bezpieczna ze wzgldu na wtki. Jeli chcesz, by tak
bya, musisz zarezerwowa nowy obiekt, wykona niepodzieln operacj podmiany
go i zmiennej instancyjnej, a nastpnie zwolni star warto. Jest to fatalny po-
mys, bo ciko obj rozumem kod, który zawiera tak duo drobiazgowej obsugi
wspóbienoci, a ilo zmarnowanego cache’u przewyszy zyski z równolegego
wykonania. Jeli naprawd potrzebujesz równolegego wykonania, lepiej uyj zade-
klarowanych waciwoci do wygenerowania akcesoria, zamiast pisa go rcznie.

Automatyczne zliczanie referencji


Wraz z wydaniem iOS 5 i Mac OS X 10.7 firma Apple wprowadzia automa-
tyczne zliczanie referencji (Automatic Reference Counting — ARC). Koncep-
cyjnie polega to na tym, e kompilator sam decyduje, kiedy powinien wywoa
–retain oraz –release, i robi to za Ciebie. Rzeczywista implementacja jest oczy-
wicie nieco bardziej skomplikowana.
Zamiast wstawia bezporednio do kodu wysyanie wiadomoci, kompilator wstawia
wywoania funkcji takich jak objc_retain() i objc_release(). Nastpnie opty-
malizator stara si poczy lub wyeliminowa te wywoania. W prostym przypadku
funkcje wykonuj prac analogiczn do wysyanych wiadomoci. Jednak w niektó-
rych przypadkach s znacznie bardziej efektywne.

Kup książkę Poleć książkę


54 Rozdzia 3 ‹ Zarzdzanie pamici

Wikszo przykadów w tej ksice korzysta z rcznego zliczania


referencji. Jest to celowe. Pomimo e stosowanie ARC jest zalecane
w nowych projektach, istnieje duo starego kodu, który z niego nie
korzysta. Nawet jeli wykorzystujesz ARC, wci powiniene rozumie
istot wykonywanego za Ciebie pozyskiwania i zwalniania referencji.
Podobnie warto zna zestaw instrukcji procesora, nawet jeli nigdy nie
pisze si kodu w asemblerze. Programicie, który rozumie rczne
zliczanie referencji, bardzo atwo jest przestawi si na zliczanie
automatyczne.
W prostych zastosowaniach wykorzystanie ARC pozwala zapomnie o zarzdzaniu
pamici. Jeli uywasz nowej wersji rodowiska XCode, ARC jest rozwizaniem
domylnym. Jeli kompilujesz z linii komend lub przy uyciu jednego z innych
systemów budowania projektów, dodaj opcj –fobjc-arc. Teraz wystarczy tylko
zapomnie o koniecznoci pozyskiwania i zwalniania referencji.
Byoby wspaniale, gdyby ycie byo tak proste. Niestety ARC ma pewne ogranicze-
nia. Mówic konkretniej, formalizuje mtn granic midzy pamici C a obiek-
tami Objective-C, dzielc wskaniki na trzy kategorie. Silne wskaniki pozyskuj
i zwalniaj pami tak, jak widzielimy wczeniej. Sabe, którym przyjrzymy si
póniej, to niewasnociowe referencje zerowane automatycznie podczas niszczenia
obiektu. Ostatni grup stanowi niebezpieczne, niepozyskane wskaniki. S ignoro-
wane przez ARC: sam jeste odpowiedzialny za czas ycia przechowywanych w nich
obiektów.
Domylnie wszystkie wskaniki w zmiennych instancyjnych i na stosie s mocne.
Wskaniki na obiekty w strukturach nie maj wartoci domylnej i musz by
jawnie oznaczone kwalifikatorem __unsafe_unretained. Mimo e w ich przypadku
jest to jedyne dozwolone prawo wasnoci, trzeba go jawnie uy, by przypo-
mnie osobom czytajcym kod, e wskaniki te bd ignorowane przez ARC.

Zwracanie obiektów przez argumenty


bdce wska nikami
3 __weak id weak;
4 int writeBack(id *aValue)
5 {
6 *aValue = [NSObject new];
7 weak = *aValue;
8 return 0;
9 }
10
11 int main(void)
12 {

Kup książkę Poleć książkę


Zwracanie obiektów przez argumenty bdce wskanikami 55

13 @autoreleasepool
14 {
15 id object;
16 writeBack(&object);
17 NSLog(@"Obiekt: %@", object);
18 object = nil;
19 NSLog(@"Obiekt: %@", weak);
20 }
21 NSLog(@"Obiekt: %@", weak);
22 return 0;
23 }

Z pliku: writeback.m

W trybie ARC argumenty bdce wskanikami do wskaników dziaaj w dosy


skomplikowany sposób. Ich zastosowanie obejmuje zwykle dwa przypadki: prze-
kazywanie tablic lub zwracanie obiektów. Jeli przekazujesz tablic w dó stosu,
to powiniene upewni si, e zadeklarowae j jako const. Informuje to kompi-
lator, e wywoywana funkcja nie przypisze niczego do tablicy, wic ARC bdzie
móg przekaza j bez adnej skomplikowanej interwencji.
Jeli poprzez argumenty bdce wskanikami bdziesz zwraca obiekt, to ARC
utworzy dosy skomplikowany kod. W przykadzie z pocztku tego podrozdziau
wywoanie writeBack() generuje kod zbliony do tego:
id tmp = [object retain];
writeBack(&tmp);
[tmp retain];
[object release];
object = tmp;

W funkcji writeBack() nowy obiekt bdzie automatycznie usunity z pamici przed


przechowaniem go w tymczasowej wartoci. Oznacza to, e na ko cu tego procesu
object zawiera wasnociow referencj do nowego obiektu.
Jeli zadeklarowae object jako _autoreleasing id, wygenerowany kod jest
znacznie prostszy. Automatycznie zwalnia warto przechowywan pocztkowo
w object, co nie bdzie miao adnego efektu, bo wartoci pocztkow wszystkich
wskaników — nawet tych przydzielanych automatycznie — i tak jest nil, a na-
stpnie bezporednio przekazuje wskanik i oczekuje, e jeli wywoywana funkcja
go zmodyfikuje, to umieci na jego miejsce wskanik niewasnociowy (automa-
tycznie zwalniany).

Kup książkę Poleć książkę


56 Rozdzia 3 ‹ Zarzdzanie pamici

Jeli uruchomisz ten przykad, to zobaczysz, e saba referencja jest zerowana


wycznie, gdy niszczona jest pula automatycznego przydziau. We wszystkich
przypadkach funkcja writeBack() przechowuje zwolniony automatycznie obiekt
w przekazanym wskaniku i nigdy nie usuwa z pamici przekazanej wartoci.
Wywoujcy jest zawsze odpowiedzialny za upewnienie si, e do funkcji prze-
kazuje referencj niewasnociow, co czyni na jeden z dwóch sposobów: albo
upewnia si, e wskanik pokazuje na automatycznie zwalniany obiekt, albo e
jest kopi wskanika na obiekt, dla którego pozyskano referencj.
Jeli zamiast tego oznaczysz parametr sowem out (dozwolone wycznie w przypad-
ku parametrów metod, a nie funkcji C), to wywoywana metoda gwarantuje, e
nie odczyta tej wartoci. Kompilator bdzie móg wic pomin krok, w którym
wykonuje kopi wskanika przechowywanego w object przed wywoaniem.
Jeli musisz przekaza kilka obiektów w gór stosu, to powiniene prawdopodobnie
zwróci instancj NSArray. Jest kilka alternatyw, ale s wystarczajco zoone, by
nie byy warte wysiku: korzystajc z nich, atwo popeni may bd i spdzi wieki
na debugowaniu kodu. Nawet jeli uda Ci si zrobi wszystko dobrze, przypusz-
czalnie i tak metody te bd wolniejsze ni uycie NSArray.
Jeli przekazujesz kilka wartoci w dó stosu, to powiniene zadeklarowa typ
tablicy z jawnym kwalifikatorem wasnoci dla parametru, a nie typ wskanikowy.
Na przykad __unsafe_unretained id[] zamiast id*. Zapewnia to wyczenie
mechanizmu zapisu zwrotnego.

Unikanie cykli pozyskanych referencji


19 - (void)setDelegate: (id)aDelegate
20 {
21 delegate = aDelegate;
22 }

Z pliku: ivar.m

Problemem w przypadku „czystego” zliczania referencji jest to, e nie wykrywa


cykli. Jeli dwa obiekty przechowuj referencje do siebie nawzajem, aden z nich
nie zostanie nigdy zwolniony.
Generalnie nie jest to wielki problem. Struktury danych w Objective-C s zwykle
acykliczne, ale istniej przypadki, w których cykle s nieuniknione. Najpopularniej-
szym z nich jest wzorzec delegacji. Wzorzec polega na tym, e jeden obiekt imple-
mentuje jaki mechanizm, ale zarzdzanie prac przekazuje innemu obiektowi.
Wikszo frameworku AppKit dziaa w ten sposób.

Kup książkę Poleć książkę


Migracja do ARC 57

Obiekty potrzebuj do siebie nawzajem referencji, co momentalnie tworzy cykl.


Popularnym sposobem rozwizania problemu jest przyjcie zasady, e obiekty nie
pozyskuj na siebie referencji. Jeli przekaesz obiekt jako argument do metody
–setDelegate:, bdziesz musia upewni si, e referencja jest przechowywana przez
jaki inny obiekt lub e zostanie przedwczenie zwolniona, a obiekt usunity.
W przypadku ARC masz dwie moliwoci: moesz oznaczy zmienn instancyjn
sowem __weak albo __unsafe_unretained. Pierwsza z opcji jest bezpieczniejsza,
bo zapewnia, e wskanik nie bdzie „wisia w powietrzu”. Gdy delagata zostanie
zniszczona, zmienna instancyjna zostanie ustawiona na nil.
S dwie wady uywania sabych wskaników. Pierwsz jest przenono. Sabe
wskaniki dziaaj na iOS 5, Mac OS X 10.7 i w GNUstep, ale nie dziaaj na
starszych wersjach iOS i Mac OS X. Drug wad jest wydajno. W kadej próbie
dostpu do wskanika poredniczy funkcja pomocnicza, sprawdzajca, czy obiekt
nie jest w stanie dealokacji, i pozyskujca referencj do niego, jeli jest wci
„ywy”, albo zwracajca nil w przeciwnym przypadku.
Pod nazw niebezpiecznych, niepozyskanych wskaników kryj si zwyke, „tra-
dycyjne” wskaniki, oferujce tani dostp do obiektu i dziaajce na kadej plat-
formie sprztowej. Ich wad jest obarczanie uytkownika odpowiedzialnoci za
upewnienie si, e po zwolnieniu wskazywanego obiektu uytkownik nie signie
ju wicej do wskanika.
Dobrym kompromisem jest uywanie sabych wskaników w trakcie debugowa-
nia i niebezpiecznych, niepozyskanych wskaników w trakcie normalnej pracy.
Dodaj asercj sprawdzajc, czy wskanik nie jest równy nil, przed wysaniem mu
jakiejkolwiek wiadomoci, a jeli bdziesz mia bdy, to sko czysz z uytecznym
komunikatem zamiast nagego przerwania aplikacji.

Migracja do ARC
Jeli zaczynasz nowy projekt w XCode, ARC bdzie domylnym wyborem i ciko
znale powody, by z niego nie skorzysta. Jeli jednak pracujesz ze starszym ko-
dem, prawdopodobnie bdziesz uywa rcznego zliczania referencji. W dugiej
perspektywie mona oszczdzi sobie pracy, przenoszc kod do ARC, ale jest to
nieco trudniejsze ni ustawienie przecznika kompilacji.
Clang posiada narzdzie wspomagajce migracj, które próbuje przepisa kod
Objective-C tak, by korzysta z ARC. Wywouje si je z linii komend przy uyciu ar-
gumentów –ccc-arcmt-check i –ccc-arcmt-modify. Pierwszy z nich informuje
o wszystkich miejscach w kodzie, które nie mog by automatycznie zmienione.
O ile nie bdzie bdów, drugi wykona konwersj kodu, modyfikujc oryginalny plik.

Kup książkę Poleć książkę


58 Rozdzia 3 ‹ Zarzdzanie pamici

W prostym kodzie Objective-C narzdzie zadziaa poprawnie. Najbardziej oczy-


wistymi zmianami bdzie usunicie wszystkich wiadomoci –retain, –release
i autorelease. Narzdzie usunie take jawne wywoanie [super dealloc] z metody
–dealloc. Od teraz wywoanie jest wstawiane automatycznie przez kompilator.
ARC automatycznie zwalnia wszystkie zmienne instancyjne, wic metod –dealloc
bdziesz musia zaimplementowa, tylko jeli musisz zwolni pami zajt przez
funkcj malloc() lub podobne konstrukcje.
Jeli utworzye wasne metody do zliczania referencji, bdziesz musia je usun.
Popularnym powodem wasnej implementacji jest ch uniknicia przypadkowego
usunicia singletonów. Traci to na znaczeniu w przypadku ARC, poniewa bd
programisty ma mniejsze szanse na spowodowanie przedwczesnego usunicia
obiektu.
Do zwalniania zmiennych instancyjnych ARC tworzy metod –.cxx_
destruct. Metoda ta bya pierwotnie utworzona, by po zniszczeniu
obiektu automatycznie wywoywa destruktory z C++. Widoczn ró-
nic pomidzy jej dawnym zastosowaniem a ARC w Objective-C jest to,
e zmienne instancyjne s teraz dealokowane po wykonaniu funkcji
–dealloc w klasie-korzeniu, a nie przed. W wikszoci przypadków nie
powinno mie to znaczenia.
Najwiksze problemy pojawiaj si, jeli próbujesz przechowa wskaniki Ob-
jective-C w strukturach C. Najprostszym rozwizaniem jest po prostu nierobienie
tego. W zamian uyj obiektów Objective-C z publicznymi zmiennymi instancyjnymi.
Pozwoli to kompilatorowi zaj si zarzdzaniem pamici obiektu i jego pól.
Jedynym przypadkiem, w którym uznaje si, e uywanie struktur odnoszcych si
do obiektów Objective-C jest bezpieczne, jest sytuacja, gdy przekazujesz je w dó
stosu. Wskaniki na obiekty mog posiada kwalifikator __unsafe_unretained
tak dugo, jak dugo pozostaj poprawne w funkcji, w której powstay.
Po uyciu narzdzia do migracji zauwaysz, e znikny waciwoci assign. Zostay
one przepisane jako unsafe_unretained lub weak, w zalenoci od tego, czy wy-
brana platforma docelowa kompilacji obsuguje sabe referencje. Jeli waciwoci
assign wykorzystywae do przerywania prostych cykli i uznasz, e sabe referencje
stwarzaj problemy wydajnociowe, moesz jawnie zmieni niektóre z nich na
unsafe_unretained.
Narzdzie do migracji spróbuje w odpowiednich miejscach powstawia rzutowanie
mostkowane __bridge, ale warto sprawdzi, czy zrobio to poprawnie. Rzutowania
te s wykorzystywane do dodawania i usuwania obiektów z kodu zarzdzanego
przez ARC. W kodzie niewykorzystujcym ARC mona korzysta z konstrukcji ta-
kich jak (void*)someObject, bo wskaniki na obiekty s zwykymi wskanikami C,

Kup książkę Poleć książkę


Pule automatycznego zwalniania pamici 59

do których dodatkowo mona wysya wiadomoci. W trybie ARC rzutowanie


byoby wieloznaczne, bo kompilator nie wiedziaby, która zmienna ma by waci-
cielem obiektu wskazywanego przez void*. Z tego powodu taki kod jest zabroniony.
Narzdzie do migracji przepisze przedstawion wyej konstrukcj jako (__bridge
void*)someObject, ale moe to nie by to, o co Ci chodzio. Tego typu rzutowaniom
bardziej szczegóowo przyjrzymy si w podrozdziale „Wspópraca z C”.

Pule automatycznego zwalniania pamici


3 id returnObject(void)
4 {
5 return [[NSObject new] autorelease];
6 }
7
8 int main(void)
9 {
10 @autorelease {
11 id object = returnObject();
12 [object retain];
13 }
14 // Tutaj obiekt traci wano.
15 [object release];
16 return 0;
17 }

Z pliku: autorelease.m

Poza cyklami najwikszym problemem w przypadku zliczania referencji s krótkie


okresy, w których na obiekt nie wskazuje adna referencja. W jzyku C problemem
jest decyzja, kto jest odpowiedzialny za alokowanie pamici: wywoujcy czy wy-
woywany.
W funkcjach takich jak sprintf() pami zajmuje wywoujcy. Niestety nie wie on,
ile pamici tak naprawd jest potrzebne, wic utworzono wariant o nazwie snprintf(),
który informuje wywoan funkcj o iloci dostpnej pamici. Takie rozwizanie
wci moe sprawia problemy, wic utworzono jeszcze jedn wersj o nazwie
asprintf(), która pozwala wywoywanej funkcji zaj si alokowaniem pamici.
Jeli pami zajmuje wywoywana funkcja, kto jest odpowiedzialny za jej zwol-
nienie? Prawdopodobnie wywoujcy, ale poniewa to nie on zaj pami, to
programy sprawdzajce równowag midzy wywoaniami funkcji malloc() i free()
nie poradz sobie ze spostrzeeniem potencjalnego wycieku pamici.

Kup książkę Poleć książkę


60 Rozdzia 3 ‹ Zarzdzanie pamici

W Objective-C problem ten wystpuje jeszcze czciej. Wiele metod moe zwraca
obiekty tymczasowe, które musz zosta zwolnione. Z kolei gdy zwracaj wskanik
na zmienn instancyjn, nie trzeba go zwalnia. Mona by najpierw pozyskiwa
takie wskaniki, ale potem trzeba by pamita, eby zwalnia kady obiekt zwra-
cany z metody. Szybko staoby si to mczce.
Rozwizaniem problemu jest pula automatycznego zwalniania pamici. Po wy-
saniu do obiektu wiadomoci –autorelease jest on dodawany do aktywnej w danym
momencie puli NSAutoreleasePool. Gdy instancja puli jest niszczona, kademu
dodanemu do niej obiektowi jest wysyana wiadomo –release.
-autorelease to opóniona wiadomo –release. Wysya si j do obiektu, gdy
samemu nie potrzebuje si ju referencji do niego, ale komu innemu moe jeszcze
by potrzebna.
Jeli uywasz ptli wykonania NSRunLoop, pula automatycznego zwalniania pa-
mici bdzie tworzona na pocztku, a niszczona na ko cu kadej iteracji ptli.
Oznacza to, e aden tymczasowy obiekt nie zostanie zniszczony do ko ca obec-
nej iteracji. Jeli robisz co, co wymaga duej iloci takich obiektów, moesz
chcie utworzy now pul automatycznego zwalniania. Robi si to w nastpujcy
sposób:
id pool = [NSAutoreleasePool new];
[anObject doSomethingThatCreatesObjects];
[pool drain];

Zwró uwag, e aby zniszczy pul, trzeba jej wysa wiadomo –drain, a nie
–release. Jest tak, bo w trybie odmiecania pamici rodowisko uruchomieniowe
Objective-C ignoruje wiadomoci –release. Wiadomo –drain jest wskazówk
dla odmiecacza, ale w trybie odmiecania pamici nie powoduje natychmiastowego
zniszczenia puli.
W OS X 10.7 firma Apple uczynia pul automatycznego zwalniania pamici
czci jzyka. Programy jawnie uywajce NSAutoreleasePool s uwaane za
niepoprawne w trybie ARC i zostan odrzucone przez kompilator. Trzeba je za-
stpi konstrukcj @autoreleasepool, definiujc region wanoci puli. W trybach
innych ni ARC konstrukcja ta spowoduje wstawienie identycznego kodu jak w li-
stingu powyej. W trybie ARC wstawione zostan wywoania funkcji objc_
autoreleasePoolPush() i objc_autoreleasePoolPop(), które wykonaj podobn prac.

Kup książkę Poleć książkę


Konstruktory automatycznie zwalniajce pami 61

Konstruktory automatycznie zwalniajce pami


4 + (id)object
5 {
6 return [[[self alloc] init] autorelease];
7 }

Z pliku: namedConstructor.m

W poprzednim podrozdziale powiedziaem, e obiekty utworzone przy uyciu +alloc


maj licznik referencji ustawiony na jeden. W rzeczywistoci wszystkie obiekty
s tworzone z licznikiem ustawionym na jeden, ale obiekty tworzone przy uyciu na-
zwanego konstruktora, np. +stringWithFormat: lub +array, s take automatycznie
usuwane z pamici.
By zachowa obiekt tworzony przy uyciu jednego z tych mechanizmów, trzeba
wysa mu wiadomo –retain. W przeciwnym wypadku zostanie zniszczony
w trakcie usuwania puli automatycznego zwalniania pamici.
Jest to konwencja, któr warto naladowa we wasnych klasach. Jeli kto utworzy
instancj jednej z Twoich klas, korzystajc z nazwanego konstruktora, bdzie
oczekiwa, e nie musi jej zwalnia. Typowy nazwany konstruktor przypominaby
ten z pocztku tego podrozdziau.
Zwró uwag, e poniewa jest to metoda klasowa, obiekt self bdzie klas. Wy-
syajc wiadomo +alloc do self zamiast do klasy o okrelonej nazwie, metoda
moe dziaa poprawnie równie w przypadku podklas.
W trybie ARC te konwencje zostay sformalizowane w rodzinach metod. Metody,
które zaczynaj si od sów alloc, new, copy lub mutableCopy, zwracaj referencj
wasnociow — referencj, która musi zosta zwolniona, jeli nie bdzie prze-
chowywana. Inne metody zwracaj referencje niewasnociowe, które musz zosta
automatycznie zwolnione lub przechowane w miejscu, co do którego gwarantuje
si, e nie bdzie zwolnione.

Automatyczne zwalnianie obiektów w akcesorach


34 - (NSString*)stringValue
35 {
36 return [[string retain] autorelease];
37 }

Z pliku: ivar.m

Kup książkę Poleć książkę


62 Rozdzia 3 ‹ Zarzdzanie pamici

Innym powszechnym problemem ze zliczaniem referencji w formie zaimplemento-


wanej przez Foundation jest czste niepozyskiwanie obiektów, które znajduj si
na stosie. Rozwamy nastpujcy fragment kodu:
NSString *oldString = [anObject stringValue];
[anObject setStringValue: newString];

Jeli metoda –setStringValue: zostaa zaimplementowana tak, jak sugerowaem


wczeniej, to wykonanie kodu sko czy si przerwaniem aplikacji, bo obiekt, do
którego odnosi si oldString, zostanie usunity przed ustawieniem nowej wartoci
cigu znakowego. Jest to problem majcy dwa moliwe rozwizania, obydwa ko-
rzystajce z puli automatycznego zwalniania pamici. Pierwsze polega na auto-
matycznym zwolnieniu starej wartoci podczas ustawiania nowej. Drugi to takie
zdefiniowanie metody –stringValue, jak pokazano na pocztku tego podrozdziau.
Zapewnia to, e cig znakowy nie zostanie przez przypadek zniszczony w trakcie
normalnej pracy obiektu. Innym popularnym rozwizaniem jest zastpienie wia-
domoci –copy wiadomoci –retain. Jest to uyteczne, jeli zmienna instancyjna
moe by modyfikowana. Jeli nie mona jej modyfikowa, –copy bdzie odpo-
wiednikiem –retain. Jeli mona j modyfikowa, wywoujcy otrzyma obiekt, który
nie bdzie ulega zmianom na skutek wysanych mu wiadomoci.

Wsparcie dla automatycznego odmiecania kolekcji


0 $ gcc -c -framework Cocoa -fobjc-gc-only
collected.m
1 $ gcc -c -framework Cocoa -fobjc-gc collected.m

Od wersji OS X 10.5 firma Apple wprowadzia do Objective-C automatyczne od-


miecanie kolekcji. Cho moe to upraszcza ycie programistom, w wikszoci
przypadków zmniejsza wydajno. Odmiecacz firmy Apple do ledzenia istnie-
jcych referencji zuywa duo pamici i z tego powodu nie jest dostpny na iPhone’a.
Nie jest te obsugiwany w starszych wersjach OS X, a jego obsuga w GNUstep
jest ograniczona. Jeli chcesz pisa przenony kod, powiniene unika odmiecania
kolekcji.
Jeli skompilujesz kod w trybie odmiecania pamici, wszystkie wiadomoci
–retain, –release i –autorelease zostan zignorowane. Kompilator automatycznie
wstawi wywoania odpowiednich funkcji przy kadej operacji zapisu do pamici
na stercie.

Kup książkę Poleć książkę


Wsparcie dla automatycznego odmiecania kolekcji 63

eby mona byo uywa odmiecania kolekcji, kod musi by skompilowany w try-
bie odmiecania pamici. Przy kadej operacji przypisania do pamici na stercie
wstawiane s wtedy wywoania funkcji, które w rodowisku uruchomieniowym
systemu Mac s zadeklarowane w pliku objc-auto.h.
Funkcje te upewniaj si, e odmiecacz kolekcji jest wiadomy wykonanego
przypisania. S wymagane, bo odmiecacz dziaa w tle, w osobnym wtku, usu-
wajc obiekty, do których nie moe znale referencji. Odmiecacz musi by in-
formowany o przestawianiu wskaników; mógby przez przypadek usun obiekt,
do którego przed momentem utworzye referencj.
Podczas kompilacji z wczonym odmiecaniem pamici dostpne s dwie opcje. Po
skompilowaniu z flag –fobjc-gc-only kod bdzie wspiera wycznie odmiecanie
kolekcji. Po skompilowaniu z flag –fobjc-gc kod bdzie obsugiwa zarówno
zliczanie referencji, jak i automatyczne odmiecanie kolekcji. Jest to uyteczne, gdy
kompilujesz framework. Wci musisz pamita, by w odpowiednich miejscach
doda wywoania –retain i –release, ale uytkownicy frameworku bd mogli
uywa go z wczonym lub wyczonym odmiecaniem.

110 OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(


id predicate, id replacement, volatile id *
objectLocation)
111 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
112 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapGlobalBarrier(id
predicate, id replacement, volatile id *
objectLocation)
113 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
114 // automatyczna aktualizacja zmiennej instancyjnej
115 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariable(id
predicate, id replacement, volatile id *
objectLocation)
116 __OSX_AVAILABLE_STARTING(__MAC_10_6,
__IPHONE_NA) OBJC_ARC_UNAVAILABLE;
117 OBJC_EXPORT BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier
(id predicate, id replacement, volatile id *
objectLocation)

Kup książkę Poleć książkę


64 Rozdzia 3 ‹ Zarzdzanie pamici

Wspópraca z C
W trybie odmiecania pamici nie jest skanowana caa pami. Dane zaalokowane
przy uyciu malloc() s niewidoczne dla odmiecacza. Jeli przekaesz do funk-
cji z C wskanik na obiekt w parametrze void*, a nastpnie funkcja przechowa go
w pamici zarezerwowanej malloc(), stanie si niewidoczny dla odmiecacza i moe
zosta zwolniony, cho wci istniej do niego referencje.
W trybie ARC kompilator automatycznie zajmie si wskanikami na stosie i zmien-
nymi instancyjnymi, ale nie bdzie ledzi wskaników w strukturach i wszystkich
innych jawnie zadeklarowanych jako __unsafe_uretained.
Normalnie przed wstawieniem obiektu na stert wysaby mu wiadomo –retain.
Nie dziaa to jednak w trybie odmiecania pamici i jest zabronione w trybie
ARC. W zamian musisz uy funkcji CFRetain(), inkrementujcej licznik refe-
rencji obiektu niezalenie od obecnoci odmiecacza. Odmiecacz zwolni obiekt je-
dynie wtedy, gdy licznik referencji osignie warto zero i nie bdzie mona zna-
le do niego adnej referencji w skanowanej pamici.
Gdy sko czysz prac z referencj znajdujc si poza obszarem ledzonym przez
odmiecacz, bdziesz musia wywoa CFRelease().
ARC posiada bogatszy model pamici do tego typu operacji. Jawne rzutowania
obiektów na nieobiektowe wskaniki nie s ju dozwolone. Musz by zastpione
rzutowaniami mostkowanymi. Rozwamy nastpujcy fragment kodu dziaajcy
w trybie innym ni ARC:
void *aPointer = (void*)someObject;

W trybie ARC rezultatem wykonania go byoby utworzenie ze wskanika ledzo-


nego wskanika nieledzonego. Nie jest to zamiana, któr chciaby wykona bez
zastanowienia. Masz trzy podstawowe moliwoci. Pierwsza jest czsto wykorzy-
stywana w przypadku zmiennych na stosie lub wskaników pokazujcych na
obiekty, co do których ma si pewno, e wskazuj na nie inne referencje:
void *aPointer = (__bridge void*)someObject;

Powyej wykonywane jest rzutowanie bez przekazania wasnoci. Jeli wszystkie


pozostae referencje na someObject przestan istnie, aPointer zostanie wiszcym
wskanikiem.
Jeli wskanik void* bdzie umieszczony na stosie z zamiarem przechowania wa-
snociowej referencji do obiektu, powiniene wykona rzutowanie mostkowane:
void *aPointer = (__bridge_retained void*)
someObject;

Kup książkę Poleć książkę


Niszczenie obiektów 65

Spowoduje to wyjcie jednej referencji wasnociowej spod kontroli ARC. Jest to


z grubsza odpowiednik wysania do someObject wiadomoci –retain przed prze-
chowaniem go we wskaniku. Jeli napiszesz (__bridge_retained void*)someObject
bez operacji przypisania, bdzie to informacja dla kompilatora, eby pozyska re-
ferencj na obiekt. Tego typu postpowanie uznawane jest za bardzo zy styl pro-
gramowania. Podczas rzutowania z powrotem na wskanik na obiekt powiniene
wykona odwrotn operacj:
id anotherObjectPointer = (__bridge_transfer
id)aPointer;
aPointer = NULL;

Kod ten powoduje przekazanie wasnociowej referencji pod kontrol ARC. ARC jest
teraz odpowiedzialny za zwalnianie obiektu, wic wane jest pamitanie o wy-
zerowaniu wskanika z C. Jeli nie przejmujesz wasnoci nad wskanikiem, po-
winiene uy prostego rzutowania __bridge.

Niszczenie obiektów
3 @interface Example : NSObject
4 {
5 void *cPointer;
6 id objectPointer;
7 }
8 @end
9 @implementation Example
10 - (void)finalize
11 {
12 if (NULL != cPointer) { free(cPointer); }
13 [super finalize];
14 }
15 - (void)dealloc
16 {
17 if (NULL != cPointer) { free(cPointer); }
18 #if !__has_feature(objc_arc)
19 [objectPointer release];
20 [super dealloc];
21 #endif
22 }
23 @end

Z pliku: dealloc.m

Istniej trzy metody wywoywane podczas niszczenia obiektu zalenie od wyko-


rzystywanego trybu. Jedna jest uruchamiana za kadym razem, ale nie moe by
napisana przez Ciebie. Metoda –.cxx_destruct jest zawsze wywoywana przez

Kup książkę Poleć książkę


66 Rozdzia 3 ‹ Zarzdzanie pamici

rodowisko uruchomieniowe Objective-C i zajmuje si niszczeniem pól, za któ-


rych czyszczenie jest odpowiedzialny kompilator. Do kategorii tej nale obiekty
C++ w trybie Objective-C++ i wskaniki na obiekty Objective-C w trybie ARC.
Dwie pozostae metody to –finalize i –dealloc. W trybie odmiecania pamici
nie musisz nic robi, by usun referencje do obiektów Objective-C, ale wci
musisz wykona czyszczenie zasobów, którymi nie zarzdza odmiecacz pamici.
Do tej kategorii naley zamykanie uchwytów do plików, zwalnianie pamici za-
alokowanej przy uyciu malloc() itd. Jeli klasa ma zmienne instancyjne, które
wymagaj rcznego czyszczenia, powiniene zadeklarowa metod –finalize.
Odmiecacz pamici zwykle wywoa metody –finalize w specjalnym
wtku. Oznacza to, e metody –finalize musz by bezpieczne ze
wzgldu na wtki. Jeli korzystaj z globalnych zasobów, musz upew-
ni si, e nie spowoduje to problemów.
Jeli nie uywasz odmiecania pamici, sprztanie powiniene wykona w metodzie
–dealloc. Zawarto metody zaley od tego, czy uywasz ARC. Dawniej metody –
dealloc byy wypenione wiadomociami –release wysyanymi do kadej
zmiennej instancyjnej, któr deklarowaa klasa. Jeli korzystasz z ARC, nie
jest to wymagane. ARC zwolni wszystkie wasnociowe referencje do obiektów
w –.cxx_destruct, wic w –dealloc bdziesz musia sprztn jedynie zmienne in-
stancyjne niebdce obiektami.
Zarówno w trybie odmiecania pamici, jak i rcznego pozyskiwania i zwalniania re-
ferencji powiniene przekaza wiadomo do nadklasy, wywoujc [super dealloc]
lub [super finalize]. W trybie ARC jawne wywoanie –dealloc jest niedozwolone.
Zamiast tego ARC sam wstawi wywoanie [super dealloc] na ko cu metody
–dealloc w kadej klasie niebdcej korzeniem.
Zwró uwag, e kod na pocztku tego podrozdziau jest nadmiernie skompliko-
wany. W prawdziwym kodzie mao prawdopodobne jest, eby musia wspiera
zarówno tryb ARC, jak i tryb rcznego pozyskiwania i zwalniania referencji.
Tryby te mog wspóistnie w jednym programie, ale jedynym rozsdnym powo-
dem wspierania jakiegokolwiek trybu poza ARC jest ch zachowania zgodnoci
ze starymi kompilatorami.

Sabe referencje
4 __weak id weak;
5
6 int main(void)
7 {

Kup książkę Poleć książkę


Sabe referencje 67

8 id obj = [NSObject new];


9 weak = obj;
10 obj = nil;
11 objc_collect(OBJC_FULL_COLLECTION);
12 fprintf(stderr, "Saba referencja: %p\n", weak);
13 return 0;
14 }

Jednym z najprzyjemniejszych elementów implementacji odmiecania pamici


firmy Apple jest istnienie zerujcych si, sabych referencji. Niepozyskane wskaniki
s w starej dokumentacji Objective-C czsto okrelane mianem „sabych”. Wskaniki
te mog przetrwa duej ni obiekt, na który wskazuj. Niestety nie ma automa-
tycznego sposobu sprawdzania, czy s wci poprawne.
Sabe referencje okazay si tak przydatne podczas odmiecania pamici, e s
teraz wspierane take przez ARC, cho maj odrobin inne znaczenie. Implementacje
ARC zachowujce wsteczn kompatybilno nie obsuguj sabych referencji,
wic wsparcie firmy Apple jest obecnie jedynie na platformach OS X 10.7 i iOS 5
lub póniejszych.
Sabe referencje w rodowisku zliczania referencji s czsto uywane
do eliminowania cykli. Nie jest to konieczne w rodowisku, w którym
referencje s ledzone. W tym przypadku w miejscach potencjalnego
tworzenia cykli oraz w trakcie tworzenia delegat moesz uywa sil-
nych referencji.
Jeli zadeklarujesz wskanik na obiekt ze sowem __weak, utworzysz zerujc si,
sab referencj. Odmiecacz pamici nie wemie jej pod uwag podczas ustalania,
czy obiekt wci istnieje, a w trybie ARC po przypisaniu do niej nie zostanie zwik-
szony licznik referencji. Jeli wszystkie referencje do obiektu s sabe, moe on
by zniszczony. Po tej operacji wszystkie sabe referencje bd zwracay nil.
Sabe referencje s zwykle uywane w poczeniu z konstrukcjami takimi jak
powiadomienia. Sab referencj do obiektu mona przechowywa i wysya mu
wiadomoci tak dugo, jak dugo kto inny posiada do niego referencj. Gdy refe-
rencja przestanie istnie, obiekt mona automatycznie usun z mechanizmu po-
wiadamiania.
Cocoa posiada teraz kolekcje pozwalajce na przechowywanie sabych referencji.
Starsze wersje frameworku Foundation zawieray typy utworzone w jzyku C:
NSMapTable oraz NSHashTable wraz z zestawem funkcji C, które mona z nimi wyko-
rzysta. Interfejsy te s wci dostpne, ale w wersji 10.5 Apple zamienio te typy
na klasy.

Kup książkę Poleć książkę


68 Rozdzia 3 ‹ Zarzdzanie pamici

Typ NSMapTable jest ogólniejsz form NSDictionary. Mona w nim przechowy-


wa dowolne typy o rozmiarze wskanika zarówno w kluczach, jak i wartociach.
W trybie odmiecania pamici moesz wykorzystywa t klas do przecho-
wywania mapowa z i do silnych lub sabych wskaników. Jest to przydatne
np. w NSNotificationCenter, w którym przechowuje si obiekty mogce otrzymywa
powiadomienia. Gdy obiekty te przestan istnie, s automatycznie usuwane z ko-
lekcji, a powiadomienia nie s ju wicej wysyane.
Przykad na pocztku podrozdziau pokazuje wan rónic midzy trybami ARC
i odmiecania pamici. Jeli skompilujesz i uruchomisz go z wczonym odmie-
caniem pamici, wypisany zostanie przypuszczalnie adres obiektu. Jest tak, gdy
odmiecacz pamici podczas skanowania stosu wci widzi stare wartoci tym-
czasowe.
W odrónieniu od odmiecacza pamici w trybie ARC zawsze zostanie wypisana
warto 0. ARC jest zupenie deterministyczny. Przypisanie nil do silnego wskanika
dekrementuje licznik referencji obiektu i powoduje dealokacj. Saby wskanik
jest zerowany, nim zacznie si dealokacja, wic gwarantowane jest, e przyjmie
warto zero, nim wywoana zostanie funkcja fprintf().

Alokowanie skanowanej pamici


15 id *buffer =
16 NSAllocateCollectable(
17 10 * sizeof(id),
18 NSScannedOption);

Z pliku: gc.m

Pami zajta przy uyciu funkcji malloc() jest niewidoczna dla odmiecacza
pamici. Moe to by problemem, np. jeli potrzebujesz tablicy C zawierajcej
obiekty. Widzielimy ju rozwizanie tego problemu. Moesz wywoa CFRetain()
dla obiektu, który masz zamiar przechowa w tablicy, oraz CFRelease() dla znaj-
dujcej si w niej starej wartoci, a nastpnie je zamieni.
Nie jest to idealne rozwizanie, ale dziaa. Inn opcj jest alokacja fragmentu pa-
mici tak, by by widoczny dla odmiecacza. Funkcja NSAllocateCollectable()
jest podobna do malloc() z dwoma istotnymi rónicami.
Po pierwsze: zwracana przez ni pami bdzie odmiecana. Nie istnieje jej odpo-
wiednik w postaci funkcji NSFreeCollectable(). Gdy ostatni wskanik na bufor
zniknie, bufor zostanie usunity.

Kup książkę Poleć książkę


Alokowanie skanowanej pamici 69

Odmiecacz firmy Apple nie wspiera wskaników do wntrza bufora,


wic musisz upewni si, e utrzymujesz wskanik na pocztek re-
gionu. Inne wskaniki nie powstrzymaj procesu usunicia go.

Drug rónic jest istnienie w tej funkcji drugiego parametru, definiujcego po-
dany typ pamici. Jeli chcesz uywa bufora do przechowywania typów C,
moesz wstawi tu zero. Jeli przekaesz NSScannedOption, zwrócony bufor bdzie
przeszukiwany jako moliwe ródo wskaników na obiekty oraz wskaników na
inne obszary pamici zwracane przez NSAllocateCollectable().

Kup książkę Poleć książkę


70 Rozdzia 3 ‹ Zarzdzanie pamici

Kup książkę Poleć książkę


Skorowidz

A C System, 176
User, uytkownik, 176
abstrakcyjna nadklasa, 82 Chisnall David, 9 domeny
adres URL, 213 cig formatujcy, 103 systemu plików, 175
aktywna ptla wykonania, 211 cig znakowy ustawie , 136
algebraiczny system typów, 17 dzielenie, 101 domknicie, 189
aplikacje Cocoa, 146 kodowanie, 98
ARC, 54, 57 dostp do wartoci, 147
kopiowanie, 101 dwufazowe tworzenie
archwizowanie obiektów, 74 porównywanie, 94
arytmetyka staopozycyjna, 89 obiektów, 71
przetwarzanie, 96 dyrektywa
ASCII, 98 przycinanie, 100
atrybuty pliku, 170 @encode(), 48
tworzenie, 94, 103 @implementation, 37
automatyczne wzorce, 105
obudowywanie, @selector(), 31
Clang, 22, 23 @synthesize, 42
auto-boxing, 150 cykl, 57
odmiecanie kolekcji, 62 dziedziczenie z kolekcji, 118
zliczanie referencji, 53 dzielenie cigów
zwalnianie pamici, 60
D znakowych, 101
data, 125
B data odniesienia, 124 E
debuger enumerator, 115
Berkley Sockets API, 205 GNU, 215
bezkosztowa obsuga Erlang, 155
LLVM, 216
wyjtków, 156
deklarowanie
biblioteka
klas, 31 F
GNUstep Base, 25 firma NeXT, 25
typów, 26
libdispatch, 195 format
delegowanie, 79
libobjc, 18 JSON, 134
DNS-SD, 207
blok OpenStep, 133
@finally, 161 dodawanie metod, 36
dodawanie zmiennych, 232 framework
@try, 161 Application Kit, 19
bloki, 49, 116 domena, 164
Local, lokalne, 176 Cocoa, 18
bd w kodzie, 164
Network, sie, 176 Foundation Kit, 19, 51
bdy, 155

Kup książkę Poleć książkę


236 Skorowidz

funkcja strtok_r(), 101 NSCalendar, 125


_ autoreleasePoolPush(), time(), 124 NSDate, 124, 125
60 writeBack(), 55 NSDateFormatter, 126
_Block_copy(), 50, 193 funkcje NSDecimal, 89
_Block_release(), 193 anonimowe, 49, 189 NSDictionary, 148
_start, 142 konwertujce, 99 NSDistantObject, 209
alarm(), 128 NSError, 164
asprintf(), 59, 103 G NSException, 159, 219
CFRetain(), 64 GCC, 46 NSFileHandle, 206, 207
class_conforms GNUstep runtime, 22 NSFileManager, 169, 170
´ToProtocol(), 229 NSIndexSet, 111
dispatch_get_global_ NSMutableArray, 111
´queue(), 196 H NSNotificationQueue, 201
ETGetOptionsDictionary(), hierarchia NSControl, 80 NSProcessInfo, 141
143 NSPropertyList
exit(), 145 I ´Serialization, 132
fprintf(), 68 inicjalizacja statyczna, 46 NSRecursiveLock, 182
free(), 59 inspekcja obiektów, 215 NSRegularExpression, 105
getaddrinfo(), 207 Instance Method Pointer, 28 NSRunLoop, 128
getCounter(), 49, 50 instancja NSScanner, 92, 127
getopt(), 143 NSDecimalNumber, 89 NSSet, 112, 117
gettimeofday(), 126 NSFont, 107 NSThread, 180
longjmp(), 156 singletonu, 82 NSTimer, 84, 128
main(), 47 interfejs kqueue(), 206 NSURLConnection, 213
malloc(), 59 ivar, 33 NSURLRequest, 213
memcpy(), 73 ivars, 26, 52, 232 NSUserDefaults, 136, 137
NSAllocateCollectable(), NSView, 80
68 J Pair, 82
NSClassFromString(), 230 TypedArray, 119
NSLog(), 104, 221 jednostka zarzdzania UIApplication, 128
objc_autorelease pamici, 168 klastry klas, 82, 86, 96
´PoolPop(), 60 jzyk klasy
objc_exception_throw(), Smalltalk, 17 inspekcja, 229
219 StrongTalk, 17 odszukiwanie, 228
objc_msg_lookup(), 217 JSON, JavaScript Object odszukiwanie wedug
objc_msgSend(), 217, 224 Notation, 134 nazwy, 224
objc_release(), 53 tworzenie, 231
objc_retain(), 53 K kodowanie
object_getClass(), 45 kalendarz, 125 klucz-warto, 114, 147
object_getIndexedIvars(), kanoniczne ustawienia tekstu, 99
232 regionalne, 91, 96 typów, 47
object_setClass(), 45 kategorie, 36, 139 typu, 48
printf(), 91, 103 klasa typu Objective-C, 86
qsort(), 31 LKMessageSend, 77 UTF-8, 93
scanf(), 91 NSApplication, 128 kolejka FIFO, 196
sprintf(), 59, 91 NSArray, 110 kolekcje, 109
sscanf(), 91 NSAssertionHandler, 220 kompilator GCC, 23
strsep(), 101 NSAttributedString, kompilowanie programów, 23
strtok(), 101 106, 107

Kup książkę Poleć książkę


Skorowidz 237

konstrukcja +pathWithComponents, N
@autoreleasepool, 60 172
konwersja cigu znakowego, +stringWithFormat, 90 nadklasa
90 –addToQueue, 186 NSObject, 33
kopiowanie obiektów, 72 –compare, 96 NSProxy, 33
KVC, key-value coding, 147, -countForObject, 113 nage zako czenie
151 –dealloc, 58 programu, 145
KVO, key-value observing, –description, 103 narzdzie
147, 152 –descriptionWithLocale, 90 do migracji, 58
kwalifikator –fileExistsAtPath:is gnustep-config, 24
__block, 191 ´Directory, 173 pbxbuild, 24
static, 192 –finalize, 66 plutil, 134
–forward, 227 NeXT, 20
niszczenie obiektów, 65
L –hash, 112
notacja kropkowa, 39, 151
library, biblioteka, 176 –init, 72
liczba argumentów, 103 –initWithCoder, 76
–initWithString, 139 O
liczba binarna, 89
licznik referencji, 102 –isEqualToString, 95 obiekt
licznik referencji obiektu, 52 KVC, 148 naprawiajcy, 165
linia komend, 143 –lastIndex, 111 NSAutoreleasePool, 104
Lisp, 155 –makeObjects NSCharacterSet, 92, 100
lista z przeskokami, ´PerformSelector, 116 NSColor, 138
skip list, 110 malloc(), 51 NSLocale, 144
listy waciwoci, –member, 117 self, 61
103, 129, 203 –newCopyStarted, 204 obiekty cigów znakowych, 93
–objectForKey, 136, 148 obserwacja klucz-warto, 147
–pathComponents, 172 obsuga bloków, 189
–pathForResource:of obsuga wyjtków, 157
apanie wyjtków, 157 ´Type, 174 odczytywanie pliku, 167
czenie si z serwerami, 207 –readUTF8String, 207 odmiecanie kolekcji, 63
–setDateFormat, 127 opakowywanie, boxing, 86
M –setStringValue, 62 opcja copy, 41
makro –setValue:forKey, 148 opcja –framework, 24
assert(), 220 sprintf(), 90 OpenStep, 98
CFSTR(), 94 –start, 128 OS X GCC, 23
NS_BLOCK_ASSERTS, –stringValue, 139
221 –valueForKey, 148 P
NSAssert(), 220 –writeUTF8String, 207 pakiety, bundles, 174
NSCAssert(), 220 metody ptla wykonania, 84, 128
mapa, 113 o zmiennej liczbie ptla wykonania
mechanizm powiadomie , 199 argumentów, 110 NSRunLoop, 60
mechanizm wizania, 152 wirtualne, 120 platforma POWER6, 89
metaklasy, 231 migracja, 58 plik example.plist, 130
metoda MMU, memory pliki implementacji, 32
+alloc, 72 management unit, 168 pliki nagówkowe, 32
+allocWithZone, 79 model obiektowy, 15 POD, plain old data type, 122
+bundleForClass, 175 multicast DNS, 211
+initialize, 47

Kup książkę Poleć książkę


238 Skorowidz

podklasa Rhapsody DR2, 175 StrongTalk, 17


NSEnumerator, 115 rozmiar wskanika, 86 struktura NSRange, 18
NSNumber, 90 rozszerzenie .h, 32 strukturalna obsuga
NSObject, 38 rozszerzenie .m, 32 wyjtków, 156
NSSet, 113 rozszerzenie klasy, 37 system
NSString, 83 rzucanie obiektów, 158 OPENSTEP, 146
podmiana wskanika isa, rzutowanie OS X, 22, 24
154, 232 mostkowane, 64 OS X 10.7, 23
POSIX, 142, 179 mostkowane __bridge, 58 Solaris, 19
powiadomienia wskaników, 16 Symbian, 22
kolejkowanie, 201 systemy plików, 173
przesyanie, 202 S szybkie enumerowanie,
wysyanie, 201 scheduler, 181 97, 115
danie, 199 SEH, structured exception
priorytet pliku, 175 handling, 156 
priorytet wtku, 180 selektory, 30 cieki do klucza, 151
proces przestrzeni pracy, 167 selektory typowane, 31 rodowisko uruchomieniowe
programowanie sterowane Simula, 16 GNU, 224
zdarzeniami, 84 singletony, 78 GNUstep, 22
projekt GNU, 20 skojarzone referencje, 233
protokoy nieformalne, 226 skrót obiektu, 112
protokó sabe referencje, 67
T
Collection, 37 sownik, 113 tablica asocjacyjna, 113
ETCollection, 37 NSDictionary, 159 tablice, 111
NSCoding, 76, 139 wtku, 184 test Ingallsa, 18
NSCopying, 50, 73 sowo kluczowe, 158 TLB, 195
NSLocking, 185 @defs, 44 tryb
NSObject, 35, 116 @end, 32 ILP32, 85
TCP/IP, 205 @implementation, 32 LP64, 85
przechowywanie @interface, 32, 33 tworzenie
kolekcji, 130 @private, 33 klas, 231
obiektów, 120, 138 @protocol(), 35 sownika, 113
ustawie , 135 @public, 33 wtków, 179
przedwczesna @synthesize, 42 wasnych kolejek, 196
optymalizacja, 95 __block, 49 typ
przejrzysta wersja, 135 __thread, 184 Class, 27
przesyanie obiektów, 208 __unsafe_unretained, 57 IMP, 28
pseudozmienna super, 43 __weak, 57 long, 86
punkt zatrzymania, _cmd, 42 NSDecimal, 89
breakpoint, 218 const, 27 NSMapTable, 68
nonatomic, 40 NSString*, 34
Q self, 42 NSTimeInterval, 123
sownik, 184 readwrite, 40
QTKit, 123 struct, 26 SEL, 27, 31
super, 43 unichar, 93
R this, 42 typy
referencje niewasnociowe, 52 throw, 160 podstawowe, 85
referencje wasnociowe, Smalltalk, 25, 155 wbudowane, 85
52, 61 stoper, 128 zmiennoprzecinkowe, 85

Kup książkę Poleć książkę


Skorowidz 239

U –readDataOfLength, 169 wyznaczony inicjalizator, 77


–release, 58, 60 wzajemne wykluczanie,
URL, Uniform Resource –retain, 58 muteks, 182
Locator, 212 –retainCount, 52 wzorzec
–stringForKey, 136 delegacji, 56
W –stringValue, 95 delegowania, 79
warto nil, 29, 225 –threadDictionary, 184 fasady, 80
wtki –timeIntervalSinceDate, modyfikowalnych
rywalizacja, 181 126 podklas, 27, 109
synchronizacja, 182 –UTF8String, 97 singletonu, 169
wczytywanie danych, 213 –waitForDataInBackground
wzy równolege, 210 ´AndNotify, 206 Y
wiadomoci wizania Cocoa, 151 YellowBox, 175
przekierowywanie, 227 worek, bag, 113
wysyanie, 223 wskanik, pointer, 86
wiadomo isa, 44, 45, 50 Z
+alloc, 61, 72, 82 na metody instancyjne, 28 zadeklarowane waciwoci,
+defaultCenter, 200 na NSError*, 169 39
+new, 71 na struktur, 43 zapisywanie kolekcji, 130
–autorelease, 58, 84 void*, 64 zdarzenia wywoywane
–characterIsMember, 100 wskaniki na obiekty, 26 regularnie, 180
–compare, 31 wyjtki, 155 zliczanie czasu, 126
–copy, 102 NSInternalConsistency zmienne
–copyWithZone, 73 ´Exception, 220 instancyjne, instance
–countForObject, 113 z nawracaniem, resumable variables, 26, 232
–dealloc, 51 exceptions, 163, 165 przesunicia, offset
–decimalNumberBy wyraenie @throw(), 162 variables, 33
´Adding, 89 wysyanie wiadomoci, 28 rodowiskowe, 142
–decimalValue, 89 bez argumentów, 28 warunkowe, 185
–description, 103 do instancji, 28 znak
–drain, 60 do klasy, 28 *, 48
–forwardInvocation, 209 do nil, 29 @, 48
–integerValue, 90 do obiektu, 29 ^, 48
–isEqual, 95, 112 wyszukiwanie serwisów zwracanie zera, 163
–isProxy, 45 DNS, 211

Kup książkę Poleć książkę


240 Skorowidz

Kup książkę Poleć książkę


• Kup książkę • Księgarnia internetowa
• Poleć książkę • Lubię to! » Nasza społeczność
• Oceń książkę

You might also like