it-swarm-eu.dev

Jak funguje fond NSAutoreleasePool autorelease?

Jak jsem pochopil, cokoliv vytvořené pomocí alloc , new , nebo copy musí být ručně uvolněno. Například:

int main(void) {
    NSString *string;
    string = [[NSString alloc] init];
    /* use the string */
    [string release];
}

Moje otázka by však nebyla tak platná?

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}
94
James Sumners

Ano, váš druhý kód je dokonale platný.

Pokaždé, když je objekt odeslán uživateli, je přidán do fondu autorelease. Když je bazén vyčerpán, jednoduše posílá - uvolnění do všech objektů v bazénu.

Autorelease bazény jsou prostě pohodlí, které vám umožní odložit odesílání-uvolnění až do "později". To "později" se může stát na několika místech, ale nejběžnější v aplikacích Cocoa GUI je na konci aktuálního cyklu cyklu cyklu.

65
kperryua

NSAutoreleasePool: odtok vs. uvolnění

Protože se zdá, že funkce drain a release způsobuje zmatek, může být vhodné zde objasnit (i když je to obsaženo v dokumentaci ...).

Přísně vzato, z pohledu velkého obrazu drain je ne ekvivalentní k release:

drain v referenčním prostředí provádí stejné operace jako release, takže dva jsou v tomto smyslu ekvivalentní. Chcete-li zdůraznit, znamená to, že ne únik fondu, pokud používáte drain spíše než release.

V prostředí shromážděném s odpadky je release no-op. Nemá tedy žádný účinek. drain, na druhé straně, obsahuje nápovědu pro sběratele, že by měl "sbírat v případě potřeby". Díky tomu v prostředí s odpadem používajícím drain pomáhá zamezit sblížení systému.

37
mmalc

Jak již bylo zmíněno, druhý fragment kódu je správný.

Chtěl bych navrhnout stručnější způsob využití autorelease fondu, který funguje ve všech prostředích (ref počítání, GC, ARC) a také zabraňuje zmatkům odtoku/uvolnění:

int main(void) {
  @autoreleasepool {
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
  }
}

Ve výše uvedeném příkladu si všimněte bloku @autoreleasepool. To je dokumentováno zde .

17
Neovibrant

Ne, nemáš pravdu. Dokumentace jasně uvádí, že pod non-GC, -drain je ekvivalentní -release, což znamená, že NSAutoreleasePool bude ne být unikl.

7
kperryua

Našel jsem tento odkaz poskytl nejlepší vysvětlení, kdy a jak používat NSAutoReleasePool: AutoReleasePool

1
Wayne Lo

odeslání autorelease namísto uvolnění objektu prodlouží životnost tohoto objektu alespoň do vyčerpání samotného fondu (může být delší, pokud je objekt následně uchován). Objekt může být několikrát vložen do stejného fondu, v takovém případě obdrží zprávu o uvolnění pokaždé, když byl vložen do fondu.

0
Hardik Mamtora

yeah váš kód je perfektní, kdybyste používali sběr odpadu, stačilo by jen nastavit řetězec na nulu, když jste s ním hotovi. Sběr odpadků není dobrý pro výkon vaší aplikace, takže bych nedoporučoval používat: P

0
Antwan van Houdt

Co jsem si přečetl od Apple: "Na konci bloku autorelease pool, jsou objekty, které obdržely autorelease zprávu v rámci bloku, odeslána zpráva o uvolnění - objekt obdrží zprávu o vydání pro každou dobu, kdy byla odeslána autorelease zprávu v bloku. “

https://developer.Apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

0
Gagan_iOS