19

Powiedzmy, że mam pętlę, która zwraca pęczek autoreleased obiektów NSData ...Czy w ARC nadal warto utworzyć @autoreleasepool dla pętli?

NSData* bigData = ... 
while(some condition) { 
    NSData* smallData = [bigData subdataWithRange:...]; 
    //process smallData 
} 

Pod ARC, mam jeszcze otoczyć @autoreleasepool wokół kondycji while?

NSData* bigData = ... 
@autoreleasepool { 
    while(some condition) { 
     NSData* smallData = [bigData subdataWithRange:...]; 
     //process smallData 
    } 
} 

Powodem dlaczego pytam to widzę liczbę żyjących w przydziału instrumentów przechodzących przez dach do mojego obiektów NSData że wywołanie metody dataWith... w przeciwieństwie do metody initWith.... Kiedy używam initWith..., liczba alokacji życia jest znacznie, dużo mniejsza.

Czy lepiej preferować metody initWith..., gdy tylko jest to możliwe?

Odpowiedz

13

Tak, nadal powinieneś używać puli autoreas podczas korzystania z wygodnych metod w ciasnej pętli. Wszystkie stare zasady zarządzania pamięcią nadal obowiązują w ARC, kompilator jedynie wstrzykuje dla ciebie RR. Zamów świetny post od niesamowitego Mike'a Ash!

Link

+0

Dzięki za świetny link! –

+10

Odpowiedź Per @ Chucka: @autoreleasepool musi przejść * wewnątrz * pętli, aby mogło to jakoś pomóc. Idiomem jest 'while (x) @autoreleasepool {...}', a nie '@autoreleasepool {while (x) {...}}'. – Quuxplusone

+0

Jest to zbyt uproszczone i niepoprawne. ARC może często optymalizować wykorzystanie puli autorelease w przypadku metod, które zwracają obiekt +0 (który jest najbardziej wykorzystywany w 'autoreasie'). –

7

Pod ARC, mam jeszcze otoczyć @autoreleasepool wokół kondycji chwilę?

Tak. Pule autorelease nadal są na swoim miejscu, rosną i pojawiają się jak poprzednio. Kompilator po prostu dodaje i łączy niezbędne funkcje zachowywania i zwalniania operacji, gdy włączono funkcję ARC (echo Logana), w oparciu o metody widoczne dla jednostki tłumaczeniowej i domyślne konwencje nazewnictwa.

Wykonanie w ARC jest prawie identyczne z ręcznym liczeniem odwołań: stosy puli autorelease nadal istnieją. Jedna różnica polega na tym, że kompilator może zamawiać operacje liczenia referencji nieco różniące się od sposobu, w jaki został napisany (nie w nieprawidłowy sposób) i może pominąć niepotrzebne cykle zatrzymania.

Czy lepiej preferować metody initWith ... kiedy tylko jest to możliwe?

WRT minimalizuje wzrost sterty w porównaniu do autoreleased odpowiedników: Tak. Tak zawsze było. Jest to szczególnie ważne na urządzeniach z iOS, gdzie pamięć jest dość ograniczona.

Wyjątkiem jest sytuacja, w której obiekt może uniknąć przydziału. Przykład:

NSString * copy = [NSString stringWithString:arg]; 

w tym przypadku, może być copy[[arg retain] autorelease]. Zauważ, że w tym przypadku copy jest wciąż autoreleased, ale zazwyczaj nie powinieneś testować obecności takich optymalizacji. Uwaga: Lepiej też użyć tutaj copy = [arg copy] ... [arg release].

Inną premią jest to, że twoje nierówności liczone są często wcześniej, gdy obiekt nigdy nie jest autoreleased i bliżej strony wywoławczej (a nie gdy pulę Autorelease zostanie ostatecznie pobita).

Wydajność w przypadku dużych puli autoreas jest znacznie gorsza niż przypuszczałaby większość osób. Jeśli możesz uniknąć uzależnienia od nich (np. Używając alloc + init ...+ release), możesz znacznie szybciej programować. Jawne tworzenie puli autorelease jest tanie i może pomóc zminimalizować ten problem. Gdy alokacje są duże i/lub liczne, unikaj ich używania, jeśli to możliwe, i owij te sekcje w jawne pule autorelease.

13

Myślę, że problem polega na tym, że pula autorelease ma przejść w pętlę wewnątrz. Z pętlą wewnątrz bloku autorelease, a nie odwrotnie, nagromadzone obiekty nie zostaną zwolnione, dopóki pętla nie zakończy się.

+0

Nie myślałem o umieszczeniu '@ autoreleasepool' w pętli ... dzięki za napiwek. –

Powiązane problemy