Supportvragen Mac > Programmeren in bijvoorbeeld C(++), Cocoa, Java, BASIC, en Swift

NSString versus NSMutableString

(1/2) > >>

bert:
NSString zou voor strings zijn die je niet kunt wijzigen.NSString * x;x = @"Bert";
x =  @"MacFreak";werkt echter wel. Dus toch te wijzigen? Waar zit het verschil?Bert

ridmaur:
Je wijzigt hier niet de string, je wiijzigt waar de NSString pointer genaamd x naar wijst. Of naar de string "Bert", of naar de string "MacFreak".
Je kan echter niet karakters toevoegen of verwijderen aan de string met NSString. Daar heeft NSString geen methodes voor, NSMutableString daarentegen wel.Illustratie:
NSString *name = @"Fred";
NSString *group= @"MacFreak";
NSMutableString *s;[s appendString: name];
[s appendString: @" is lid van "];
[s appendString: group];NSMutableString wordt echter niet veel gebruikt. Veelal wordt er gewoon een nieuwe NSString gedefinieerd wanneer er bijv. twee strings aan elkaar moeten worden geplakt.
NSString *name = @"Fred";
NSString *group= @"MacFreak";NSString *message = [ [name stringByAppendingString:@" is lid van "] stringByAppendingString:group];

bert:

Bedankt voor je reactie met uitleg.

--- Citaat ---ridmaur om 10:37, 26-10-2003


--- Citaat ---bert om 8:09, 26-10-2003
NSString zou voor strings zijn die je niet kunt wijzigen.NSString * x;x = @"Bert";
x =  @"MacFreak";werkt echter wel. Dus toch te wijzigen? Waar zit het verschil?Bert
--- Einde van citaat ---
Je wijzigt hier niet de string, je wiijzigt waar de NSString pointer genaamd x naar wijst. Of naar de string "Bert", of naar de string "MacFreak".

--- Einde van citaat ---
Duidelijk. Maar betekent dat stukje code van mij dan ook een geheugenlek(je)? Ik denk nl dat Bert in het geheugen blijft staan en er niets meer is dat er naar wijst. Zo ja, hoe los ik dat op?bert

ridmaur:
Aha, geheugenbeheer in Cocoa..... Ik doe een poging, maar dit is niet een van de eenvoudigste onderdelen van Cocoa/Objective C.In het algemeen: Als je de NSString definieert binnen een methode, bijv. om een tijdelijke string manipulatie te doen hoef je je geen zorgen te maken. Bij het verlaten van de methode wordt de NSString automatisch vernietigd. Vb:- (void)doSomething
{
  NSString *theString;
  .....
  [theString doSomethingToIt];
  ....
}
Anders wordt het als je een NSString als instantie variable hebt van je class of als je een NSString meegeeft als parameter aan een method (bijv. om de waarde van een instantie te zetten). Dan komt geheugen management om de hoek kijken. In onderstaand voorbeeld wordt NSString theString gedefinieerd als instance variable van TheClass. Om de waarde van die instance variable uit te kunnen lezen en te kunnen schrijven worden twee accessor methods gedefinieerd: theString en setTheString... Immers, goed OO gebruik is dat je directe toegang tot je instance variables afschermt en de toegang regelt d.m.v. 'getters and setters'.@interface TheClass:NSObject
{
     NSString *theString;
}- (void)setTheString(NSString *s);
- (NSString *)theString;
De implementatie van de 'accesor methods' setTheString en theString zien er als volgt uit:- (void)setTheString(NSString *s)
{
  [s retain];
  [theString release];
  theString = s;
}- (NSString *)theString
{
  return theString;
}Daarnaast moet je n de init methode van de class theString alloceren;
- init
{
  ...
  ...
  NSString *theString = [[NSString alloc] init];
  ...
}En in de de dealloc methode van de class moet je de theString ook niet vergeten te dealloceren:- (void)dealloc
{
  ...
  ...
  [theString release];
}Elk object kent een retain count; een tellertje dat bijhoudt hoeveel andere objecten een referentie hebben uitstaan naar het object. Dit tellertje wordt automatisch opgehoogd met een referentie maar kan ook handmatig worden opgehoogd met de methode retain en verlaagd met de methode release. Pas als een object een retain count heeft van 0 kan het netjes worden opgeruimd. Als je de retain count van je objecten in je programma niet in de gaten houdt, creeer je potentiele memory leaks omdat objecten nooit kunnen worden opgeruimd omdat je ze niet netjes weer vrijgeeft. In het voorbeeld van setTheString wordt theString gereleased voordat je de waarde toekent. Anders zou de retainwaarde op 2 komen (1 bij initialisatie en 1 in theSetString methode) maar je wilt alleen de waarde van theString wijzigen. Als je retain niet had gedaan in setTheString en je had het object theObject van class TheClass vernietigd, dan had theString niet vernietigd kunnen worden, want de release in de dealloc van de class was niet voldoende geweest om de retain count op 0 te zetten en aldus theString vrij te geven voor 'garbage collection'.Meer info over geheugenmanagement (alloc, init, retain, release, autorelease, dealloc) kan je vinden in de Cocoa documentatie. En ook in dit artikel: http://cocoadevcentral.com/articles/000055.php

bert:
Beste Rob,Je hebt een uitgebreider antwoord gegeven dan ik bedoelde (dat met die tellertjes snap ik wel, en vind ik reuze elegant), maar ik begrijp uit het eerste gedeelte dat ik me over mijn voorbeeld geen zorgen hoef te maken: Geen geheugenlek.Het artikel dat je noemde had ik vanmiddag nog zitten lezen! Daarmee werd alles weer ietsje duidelijker, maar nog (lang) niet helemaal. Enfin, doorploegen maar!Bert

Navigatie

[0] Berichtenindex

[#] Volgende pagina

Naar de volledige versie