Vra

Ek is net begin om'n blik op die Doel-C en Kakao met die oog om te speel met die iPhone SDK.Ek is redelik gemaklik met C se malloc en free konsep, maar Kakao se verwysings tel skema het my eerder verwar.Ek is vertel dit is baie elegant sodra jy verstaan dit, maar ek is nie net oor die bult nie.

Hoe doen release, retain en autorelease werk en wat is die konvensies oor hul gebruik?

(Of versuim wat, wat het jy gelees wat gehelp het jy dit kry?)

Was dit nuttig?

Oplossing

Kom ons begin met retain en release; autorelease is regtig net 'n spesiale geval as jy die basiese begrippe verstaan.

In Cocoa, elke voorwerp hou van hoeveel keer dit word verwys (spesifiek, die NSObject basis klas implemente hierdie). Deur te bel retain op 'n voorwerp, is jy dit vertel wat jy wil om sy verwysing telling vir een. Deur te bel release, jy vertel die voorwerp wat jy laat gaan van dit, en sy verwysing telling is decremented. Indien, nadat 'n beroep release, die verwysing telling is nou nul, dan se geheue daardie voorwerp is bevry deur die stelsel.

Die basiese manier hierdie verskil van malloc en free is dat enige gegewe voorwerp doen nie hoef te bekommer oor ander dele van die stelsel gekraak omdat jy bevry geheue wat hulle gebruik. Veronderstelling almal saam speel en die behoud van / vrystelling op grond van die reëls, wanneer 'n stuk van kode behou en dan stel die voorwerp, sal enige ander stuk kode ook verwysing na die voorwerp nie geraak word nie.

Wat kan soms verwarrend is om te weet die omstandighede waaronder jy retain en release moet bel. My algemene reël is dat as ek wil op te hang aan 'n voorwerp vir 'n hele ruk (as dit 'n lid veranderlike in 'n klas, byvoorbeeld), dan moet ek seker maak verwysing telling die voorwerp se weet oor my. Soos hierbo beskryf, word verwys telling 'n voorwerp se geïnkrementeer deur te bel retain. Deur konvensie, is dit ook geïnkrementeer (stel om 1, regtig) wanneer die voorwerp is geskep met 'n "init" metode. In een van hierdie gevalle, dit is my verantwoordelikheid om release 'n beroep op die voorwerp wanneer ek klaar is met dit. As ek dit nie doen nie, sal daar 'n geheugenlek wees.

Voorbeeld van voorwerp skepping:

NSString* s = [[NSString alloc] init];  // Ref count is 1
[s retain];                             // Ref count is 2 - silly
                                        //   to do this after init
[s release];                            // Ref count is back to 1
[s release];                            // Ref count is 0, object is freed

Nou vir autorelease. Autorelease word gebruik as 'n gerieflike (en soms nodig) manier om die stelsel vertel om hierdie voorwerp vry te maak na 'n kort rukkie. Van 'n loodgieter perspektief, wanneer autorelease genoem word, NSAutoreleasePool die huidige draad se gewaarsku van die oproep. Die NSAutoreleasePool weet nou dat sodra dit kry 'n geleentheid (na die huidige iterasie van die gebeurtenis lus), kan dit release 'n beroep op die voorwerp. Vanuit ons perspektief as programmeerders, dit sorg vir 'n beroep release vir ons, so ons hoef nie te (en in waarheid te sê, ons moet nie).

Wat is belangrik om daarop te let is dat (weer, deur konvensie) die hele skepping voorwerp klas metodes terugkeer 'n autoreleased voorwerp. Byvoorbeeld, in die volgende voorbeeld, die veranderlike "s" het 'n verwysing telling van 1, maar na die gebeurtenis lus voltooi is, sal dit vernietig word.

NSString* s = [NSString stringWithString:@"Hello World"];

As jy wil op te hang op daardie string, sal jy nodig het om retain noem uitdruklik, en dan uitdruklik release dit wanneer jy klaar is.

Oorweeg die volgende (baie slinks) bietjie van kode, en jy sal 'n situasie waar autorelease vereis sien:

- (NSString*)createHelloWorldString
{
    NSString* s = [[NSString alloc] initWithString:@"Hello World"];

    // Now what?  We want to return s, but we've upped its reference count.
    // The caller shouldn't be responsible for releasing it, since we're the
    // ones that created it.  If we call release, however, the reference 
    // count will hit zero and bad memory will be returned to the caller.  
    // The answer is to call autorelease before returning the string.  By 
    // explicitly calling autorelease, we pass the responsibility for
    // releasing the string on to the thread's NSAutoreleasePool, which will
    // happen at some later time.  The consequence is that the returned string 
    // will still be valid for the caller of this function.
    return [s autorelease];
}

Ek besef al hierdie dinge is 'n bietjie verwarrend - op 'n stadium, al is, sal dit op. Hier is 'n paar verwysings wat jy gaan kry:

  • bekendstelling Apple se om geheuebestuur.
  • Cacao Programmering vir Mac OS X (4de uitgawe) , deur Aaron Hillegas - 'n baie goed geskrewe boek met baie van die groot voorbeelde. Dit lees soos 'n handleiding.
  • As jy werklik duik in is, kan jy die hoof te Big Nerd Ranch . Dit is 'n opleidingsfasiliteit rundeur Aaron Hillegas - die skrywer van die bogenoemde boek. Ek het die Inleiding tot Cacao Natuurlik is daar 'n paar jaar gelede, en dit was 'n goeie manier om te leer.

Ander wenke

As jy die proses van behou / release dan is daar twee goue reëls wat "duh" voor die hand liggend om gevestigde Cacao programmeerders is, maar ongelukkig is selde uitgespel dit duidelik vir nuwelinge verstaan.

  1. As 'n funksie wat 'n voorwerp terugkeer het alloc, create of copy in sy naam dan die voorwerp is joune. Jy moet [object release] bel as jy klaar is met dit. Of CFRelease(object), al is dit 'n Core-Stigting voorwerp.

  2. As dit nie een van hierdie woorde in sy naam het nie dan die voorwerp behoort aan iemand anders. Jy moet [object retain] bel as jy wil om die voorwerp na die einde van jou funksie te hou.

Jy sal goed bedien word om ook hierdie konvensie in funksies wat jy jouself skep volg.

(Nitpickers: Ja, daar is ongelukkig 'n paar API oproepe wat uitsonderings op hierdie reëls is, maar hulle is skaars)

.

As jy kode wil skryf vir die lessenaar en jy kan teiken Mac OS X 10.5, moet jy ten minste kyk na die gebruik van Objective-C vullisverwydering. Dit sal regtig die meeste van jou ontwikkeling te vereenvoudig -. Dit is hoekom Apple het al die moeite om dit te skep in die eerste plek, en maak dit goed presteer

As vir die reëls geheuebestuur toe nie die gebruik van GC:

  • As jy 'n nuwe voorwerp te skep met behulp van +alloc/+allocWithZone:, +new, -copy of -mutableCopy of as jy 'n voorwerp -retain, is jy neem eienaarskap van dit en moet verseker dat dit -release gestuur.
  • As jy 'n voorwerp ontvang op enige ander wyse, jy is nie die eienaar daarvan en moet nie verseker dat dit gestuur -release.
  • As jy wil om seker te maak 'n voorwerp is -release gestuur kan jy óf stuur wat jouself, of jy kan die voorwerp -autorelease en die huidige stuur autorelease swembad sal stuur dit -release (een keer per ontvang -autorelease) wanneer die swembad gedreineer.

Tipies -autorelease word gebruik as 'n manier om te verseker dat voorwerpe leef vir die lengte van die huidige geval, maar is daarna skoongemaak, want daar is 'n autorelease swembad wat Cacao se geval verwerking omring. In Cocoa, dit is ver meer algemeen om voorwerpe terug te keer na 'n oproeper wat autoreleased as dit is om objets wat die oproeper self moet loslaat terugkeer.

Doel-C gebruik Verwysing tel , wat beteken dat elke voorwerp het 'n verwysing telling. Wanneer 'n voorwerp is geskep, dit het 'n verwysing telling van "1". Eenvoudig gesproke, wanneer 'n voorwerp word na verwys (dit wil sê, iewers gestoor), dit word "behou" wat beteken sy verwysing telling verhoog deur een. Wanneer 'n voorwerp nie meer nodig is, is dit "vrygestel" wat beteken sy verwysing telling verminder deur een.

As verwysing telling 'n voorwerp se is 0, die voorwerp is bevry. Dit is basiese verwysing tel.

Vir sommige tale, verwysings word outomaties verhoog en verlaag, maar objektiewe-c is nie een van daardie tale. So het die programmeerder is verantwoordelik vir die behoud van en die vrystelling van.

'n tipiese manier om 'n metode te skryf is:

id myVar = [someObject someMessage];
.... do something ....;
[myVar release];
return someValue;

Die probleem van hoef te onthou om enige verkry hulpbronne vry te stel binne kode is beide vervelige en fout sensitiewe. Doel-C stel 'n ander konsep wat gerig is op die maak van hierdie baie makliker: Autorelease Pools. Autorelease swembaddens is spesiale voorwerpe wat op elke draad word geïnstalleer. Hulle is 'n redelik eenvoudige klas, as jy opkyk NSAutoreleasePool.

Wanneer 'n voorwerp kry 'n "autorelease" boodskap gestuur om dit te, sal die voorwerp kyk vir enige autorelease poele sit op die stapel vir hierdie huidige draad. Dit sal die voorwerp te voeg tot die lys as 'n voorwerp om 'n "release" boodskap te stuur op 'n stadium in die toekoms, wat oor die algemeen as die swembad self vrygestel word.

Met die kode hierbo, kan jy dit herskryf om korter en makliker wees om te lees deur te sê:

id myVar = [[someObject someMessage] autorelease];
... do something ...;
return someValue;

As gevolg van die voorwerp is autoreleased, ons nie meer nodig het om uitdruklik noem "release" op dit. Dit is omdat ons weet dat sommige autorelease swembad sal dit vir ons later doen.

Hopelik sal hierdie help. Die Wikipedia-artikel is redelik goed oor verwysing tel. Meer inligting oor autorelease poele kan hier gevind word. Let ook daarop dat as jy bou vir Mac OS X 10.5 en later, kan jy Xcode vertel om op te bou met vullisverwydering in staat gestel, sodat jy heeltemal ignoreer behou / release / autorelease.

Joshua (# 6591) - Die vullisverwydering dinge in Mac OS X 10.5 lyk pretty cool, maar is nie beskikbaar vir die iPhone (of as jy wil hê dat jou app uit te voer op pre-10.5 weergawes van Mac OS X).

Ook, as jy wil skryf 'n biblioteek of iets wat dalk hergebruik, met behulp van die GC af slotte enigiemand met behulp van die kode in ook die gebruik van die GC af, so as ek dit verstaan, iemand probeer om te skryf wyd herbruikbare kode geneig om gaan vir die hand besturende geheue.

As ooit, wanneer mense begin om te probeer om te her-woord die verwysing materiaal wat hulle is byna altyd kry iets verkeerd of voorsien van'n onvolledige beskrywing.

Apple bied'n volledige beskrywing van Kakao se geheue bestuur stelsel in Geheue Bestuur Programmering Gids vir Kakao, aan die einde van wat daar is'n kort, maar akkurate opsomming van die Geheue-Bestuur Reëls.

Ek sal nie voeg tot die spesifieke van behou/vrylating anders as wat jy dalk wil om te dink oor die val van $50 en kry die Hillegass boek, maar ek sou raai om in die gebruik van die Instrumente tools baie vroeg in die ontwikkeling van jou aansoek (selfs jou eerste een!).Om dit te doen, Hardloop->Begin met die prestasie gereedskap.Ek wil begin met Lekkasies wat is net een van baie van die instrumente wat beskikbaar nie, maar sal help om jou te wys wanneer jy vergeet het om te vry te laat.Dit is ophou skrikwekkend hoeveel inligting wat jy sal aangebied word met.Maar check uit hierdie handleiding te kry en gaan vinnig:
KAKAO HANDLEIDING:DIE VASSTELLING VAN DIE GEHEUE LEKKASIES MET INSTRUMENTE

Eintlik probeer om te krag lekkasies kan'n beter manier van, op sy beurt, leer hoe om dit te voorkom!Baie geluk ;)

  

Matt Dillard geskryf :

     

terug [[s autorelease] release]

Autorelease doen nie behou die voorwerp. Autorelease stel dit eenvoudig in tou later vrygelaat te word. Jy wil nie daar 'n vrystelling verklaring het.

My gewone versameling van kakao geheuebestuur artikels:

kakao geheuebestuur

Daar is 'n gratis screencast beskikbaar by die iDeveloperTV Network

Memory Management in Objective-C

NilObject se antwoord is 'n goeie begin. Hier is 'n paar aanvullende inligting wat verband hou met die handleiding geheue bestuur ( vereiste op die iPhone ).

As jy persoonlik 'n voorwerp alloc/init, dit kom met 'n verwysing telling van 1. Jy is verantwoordelik vir die skoonmaak van na dit wanneer dit nie meer nodig is, hetsy deur 'n beroep [foo release] of [foo autorelease]. vrylating skoon it up dadelik, terwyl autorelease voeg die voorwerp aan die autorelease swembad, wat outomaties sal stel dit op 'n later tyd.

autorelease is in die eerste plek vir wanneer jy 'n metode wat gevolg moet die voorwerp terug in vraag (, sodat jy kan nie met die hand stel dit, anders sal jy terugkeer 'n nul voorwerp ), maar jy don 't wil om vas te hou aan dit, óf.

As jy 'n voorwerp te bekom waar jy nie noem alloc / init om dit te kry - byvoorbeeld:

foo = [NSString stringWithString:@"hello"];

maar jy wil op te hang om hierdie voorwerp, moet jy bel [cat behou]. Anders, is dit moontlik dit sal autoreleased kry en jy sal vashou aan 'n nul verwysing (as dit sou in die bogenoemde stringWithString voorbeeld ). Wanneer jy nie meer nodig het, bel [foo release].

Die antwoorde hierbo gee'n duidelike herhaling van wat die dokumentasie sê;die probleem is die meeste nuwe mense loop in die ongedokumenteerde gevalle.Byvoorbeeld:

  • Autorelease:docs sê dit sal sneller'n release "op'n sekere punt in die toekoms." WANNEER?!Basies, jy kan reken op die voorwerp wat rondom totdat jy die uitgang van jou kode terug in die stelsel gebeurtenis lus.Die stelsel KAN die vrylating van die voorwerp enige tyd na die huidige geval siklus.(Ek dink Matt gesê dat, vroeër.)

  • Statiese snare: NSString *foo = @"bar"; - doen wat jy het om te behou of vrystelling wat?Geen.Hoe oor

    -(void)getBar {
        return @"bar";
    }
    

    ...

    NSString *foo = [self getBar]; // still no need to retain or release
    
  • Die Skepping Reël:As jy het dit, jy besit dit, en verwag om dit vry te stel.

In die algemeen, die manier waarop nuwe Kakao programmeerders kry deurmekaar is deur nie verstaan wat roetines terugkeer'n voorwerp met'n retainCount > 0.

Hier is'n uittreksel uit Baie Eenvoudige Reëls Vir Die Geheue Bestuur In Kakao:

Behoud Tel reëls

  • Binne'n gegewe blok, die gebruik van die kopie, -alloc en -behou moet gelyk wees aan die gebruik van -die vrylating en -autorelease.
  • Voorwerpe geskep met behulp van gerief constructors (bv.NSString se stringWithString) word beskou as autoreleased.
  • Implementeer'n -dealloc metode om die vrylating van die instancevariables jou eie

Die 1ste koeël sê:as jy genoem alloc (of new fooCopy), wat jy nodig het om te bel vrylating op daardie voorwerp.

Die 2de koeël sê:as jy'n gerief constructor en wat jy nodig het om die voorwerp op te hang rondom (soos met'n beeld om getrek te word later), wat jy nodig het om te behou (en dan later vrylating) dit.

Die 3de moet word selfverduidelikend.

Baie goeie inligting oor cocoadev te:

As 'n hele paar mense genoem reeds, Apple se inleiding tot geheuebestuur is by verre die beste plek om te begin.

Een nuttige skakel ek nog nie gesien genoem word Praktiese Memory Management . Jy kry dit in die middel van Apple se dokumente as jy lees deur hulle, maar dit is die moeite werd om direkte skakel. Dit is 'n briljante uitvoerende opsomming van die geheue bestuur reëls met voorbeelde en algemene foute (basies wat ander antwoorde hier probeer om te verduidelik, maar nie so goed).

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top