Chociaż jest możliwe, że znaleziony kod był po prostu niechlujny, ten wzór ma znaczenie.
"Alloc, autorelease, zachowują" zakłada, że obiekt jest wymieniony w dwóch miejscach:
- Jako wartości zwracanej na stosie wywołań (styl autorelease)
- Według FB samego SDK (zwaną dalej " retain ')
Jest to ważne, jeżeli te dwa odnośniki mogą być niezależnie wydawane. Na przykład, jeśli SDK może zwolnić swój odnośnik PRZED ukończeniem stosu wywołań i opróżnieniu puli autorelease. Ok, jest to dość dopracowane; Co mam na myśli?
Rozważ te przypadki:
a) rzeczywisty kod
_facebook = [[[[Facebook alloc] init] autorelease] retain];
_facebook ma teraz licznik zatrzymywania z 2 i oczekuje 2 dzwonić do 'uwolnienia': 1 z kimkolwiek o nazwie " retain "i 1 w pewnym momencie w przyszłości, gdy NSAutoreleaseBeac spuszcza wodę.
B) proste „alternatywa” proponowane (NIE odpowiednik)
_facebook = [[Facebook alloc] init];
_facebook ma liczbę zatrzymywania z 1 i zostaną zniszczone podczas „uwolnienie” nazywa się (potencjalnie duży problem, jeśli pula autorelease nie została jeszcze opróżniona, a stos wywołań nadal używa obiektu)
Dlaczego to ma znaczenie? Wyobraźmy sobie taki kod:
@implementation (Thinger)
+(id) make_new_thing
{
return my_copy_of_thing = [[[[Thing alloc] init] autorelease] retain];
}
+(id) forget_about_thing
{
if (my_copy_of_thing != nil) {
[my_copy_of_thing release];
my_copy_of_thing = nil;
}
}
@end
void foo() {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
id thing = [Thinger make_new_thing];
[Thinger forget_about_thing];
...
[thing useThing]; // implementation B would break here !
[pool drain];
}
Hm, co do cholery ??? –
Hmm, myślę, że lepiej odinstaluj aplikację Facebook. Oni wyraźnie nie rozumieją, co robią. – JeremyP