Vracení inicializaci objektu přes „convenience konstruktoru“

hlasů
2

Když metoda instance vrátí hodnotu, která byla inicializována s convenience konstruktoru, musím zachovat tento objekt a potom autorelease v návratu, takže když dojde k autorelease pohodlí konstruktérů, ale neodebere objekt.

Bude tento popis uvolnění před volající kód a převzít vlastnictví se udržet, nebo tak něco?

- (NSStringMutable *)test {
    NSMutableString *description = [NSMutableString stringWithString:@Test Value];
    return description;
}

Nebo by to mělo být takhle?

- (NSStringMutable *)test {
    NSMutableString *description = [NSMutableString stringWithString:@Test Value];
    [description retain];                               
    return [description autorelease];
}

Telefonní předvolba:

NSMutableString *testVar = [[NSMutableString alloc] initWithString:[object description]];
Položena 12/08/2009 v 15:54
zdroj uživatelem
V jiných jazycích...                            


5 odpovědí

hlasů
9

No, měli byste být v pohodě s:

- (NSStringMutable *)test
{
    return [NSMutableString stringWithString:@"Test Value"];
}

Toto opustí objekt s udržet počtu 1 a bude v autorelease bazénu.

Autorelease bazénu se vypustí v určitých časech - to není jako garbage collector. Pokud se provádí zpracování události (jako klepnutí na tlačítko psovoda) se autorelease pool je vyčerpán rámce, když se vrátíte z kódu zpracování událostí.

Pokud jste použil toto:

- (NSStringMutable *)test
{
    NSMutableString *description = [NSMutableString stringWithString:@"Test Value"];
    [description retain];                                                               
    return [description autorelease];
}

... pak objekt by měl zachovat počet 2 a bylo by v autorelease bazénu dvakrát, a byl by ve skutečnosti chovat stejným způsobem jako v předchozím příkladu kódu.

Odpovězeno 12/08/2009 v 16:02
zdroj uživatelem

hlasů
1

Už jsem hlasoval na správnou odpověď, budu přidávat to jako styl poznámka:

Váš kód volání nebude fungovat, protože to je volání [object description], kdy má být volání[object test]

Nemusíte se vracet proměnlivé řetězce, pokud opravdu chcete, aby bylo možné změnit řetězec. Já osobně se snažit minimalizovat nestálost v kódu Píšu, protože mám pocit, že je snazší udržet programy, pokud se změní stav jsou minimální. Vracíte se jen popis, takže nemyslím si, že to musí být proměnlivé. Vím, že to je jen několik příkladů kódu, takže možná jsem byl příliš vybíravý

Dalo by se přepsat jako:

-(NSString *)description {
    // Just return a static NSString. No need to worry about memory management.
    return @"Test Value";
}

A pokud chcete, aby bylo možné změnit hodnotu tohoto vráceného řetězce ve svém volání kódu:

NSMutableString *testVar = [[NSMutableString alloc]initWithString:[object description]];

Vzhledem k tomu, že jste volal Alloc na tento řetězec, jste jejím vlastníkem a jsou zodpovědné za uvolnění jej k nějakému budoucímu datu.

Případně můžete použít jeden z mých nejoblíbenějších kousků kódu:

NSMutableString *testVar = [[object description] mutableCopy];

To vrátí proměnlivý kopii i nezměnitelné objektu (je-li to v souladu s protokolem NSMutableCopying, samozřejmě). A je třeba poslat [testVar release]v určité fázi.

A tie to se jako skutečná odpověď na vaši otázku: pokud posíláte Alloc , kopírování , mutableCopy , nebo ponechat na objekt, pak jste vlastníkem objektu a jsou odpovědné za zasílání to uvolňovací zprávu. Můžete předpokládat, že cokoli jiného vrátí autoreleased objekt.

Opět platí, že vím, že to je jen rychlý trochu ukázkový kód, který položil otázku, ale pokud budete postupovat podle výše uvedené pravidlo, které jste dostali většinu vašich problémů správy paměti seřazených. Ve svém prvním příkladu jste poslali žádnou z těchto zpráv, takže nemusíte uvolnit všechny paměťové sami. Nicméně, máte allocve svém volání kódu, takže si vlastní testVara je třeba jej uvolnit.

Odpovězeno 12/08/2009 v 16:37
zdroj uživatelem

hlasů
1

Stačí vrátit. To je jeden z hlavních účelů autorelease. Pokud jste nastavili autorelease bazén vlastní, bazén nebude vyčerpaný až do příštího běhu smyčkou událostí. Programovací příručka pro správu paměti vysvětluje to všechno v dobrém detailu - měli byste si přečíst, že dokud se nebudete cítit pohodlně s ním.

Boční Poznámka: Pokud to nebylo bezpečné a autorelease bazén se chystá vypustit brzy nějakého bizarního důvodu, což je dva zachovává a dva autoreleases nebude dělat rozdíl. Čísla jsou stále vyrovnané, takže to ještě vyjde ven existence v určitém okamžiku.

Odpovězeno 12/08/2009 v 16:03
zdroj uživatelem

hlasů
0

Jste blízký s druhou, ale nepotřebujete zachovat pro případ, o které mluvíte tady a ve skutečnosti nemusí volat autorelease sebe.

To platí, protože stringWithString se již vrátit autoreleased objektu:

 - (NSStringMutable *)test
 {
   return [NSMutableString stringWithString:@"Test Value"];        
 }

Obecně při tvorbě objektů pomocí Objective-C, pokud voláte smíšeného konstruktor (ne volání alloc a init) návratová hodnota je vždy autoreleased tak stringWithString vrací autoreleased Object stačí vrátit.

Odpovězeno 12/08/2009 v 16:02
zdroj uživatelem

hlasů
0

No, můžete jednoduše vrátit autoreleased hodnotu. Důvodem je to, že autorelease není závislá na samotné proměnné, je to funkce autorelease bazénu, který (pokud si jej vytvořit sami) je obvykle řízena běhu smyčkou.

Odpovězeno 12/08/2009 v 15:59
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more