2009-10-23 19 views

Odpowiedz

20

Możesz mieć NSMutableString (lub inną rodzimą podklasę NSString), którą chcesz zduplikować.

NSMutableString *buffer = [NSMutableString string]; 
// do something with buffer 
NSString *immutableStringToKeepAround = [NSString stringWithString:buffer]; 

Oczywiście, można też po prostu zrobić kopię:

NSMutableString *buffer = [NSMutableString string]; 
// do something with buffer 
NSString *immutableStringToKeepAround = [[buffer copy] autorelease]; 

ale jesteś właścicielem kopii i musi zwolnić lub autorelease go.

+12

Jedną z niewielkich różnic jest to, że [autorelease [[zerowa kopia]] zwróci zero, ale [NSString stringWithString: nil] rzuci wyjątek. –

+0

Fajnie, nie wiedziałem o tym! Poręczne informacje. –

9

jako „Andy” wskazuje w # 318666, jest to związane z zarządzaniem pamięcią, cytując:

Różnica między initWithString i stringWithString że stringWithString zwraca wskaźnik automatycznego zwolniony. Oznacza to, że nie musisz go specjalnie wypuszczać, ponieważ zostanie on zaatakowany następnym razem, gdy pula auto-release wyczyści wszystkie automatycznie zwolnione wskaźniki.

Z drugiej strony initWithString zwraca wskaźnik o wartości zatrzymania 1 - musisz wywołać wydanie na tym wskaźniku, inaczej spowodowałoby to przeciek pamięci.

(Taken from here)

1

Zwraca ciąg utworzony przez skopiowanie znaków z innego danego łańcucha

[NSString stringWithString:@"some string"] 

Jest to odpowiednik

[[[NSString alloc] initWithString:@"some string"] autorelease] 
+1

[Dlaczego nie po prostu zrobić '@" jakiś ciąg "' choć? "(Http: // stackoverflow.com/questions/6280849/nsstring-stringwithstringsome-string-vs-some-string) – ma11hew28

1

Ponadto, jeśli masz wskaźnik do NSString, może to być podklasa NSString jak NSMutableString. Tak więc, jeśli chcesz zapisać ciąg znaków i mieć pewność, że nie ulegnie on zmianie, powinieneś zrobić jego kopię, a zatem stringWithString istnieje.

+2

Nie jestem pewien, czy jest to poprawne - ponieważ, jak zauważyłeś, NSMutableString jest podklasą NSString, możesz faktycznie mieć coś takiego jak ciąg 'NSString * = @ "str"; NSMutableString * mStr = [NSMutableString stringWithString: string]; 'i otrzymuje zmienny łańcuch z powrotem. – Tim

+0

@Tim: tak, to jest poprawne. – newacct

+0

Miałem na myśli, jeśli masz metodę jak - (void) setName: (NSString *) nazwa; w rzeczywistości nie wiesz, czy nazwa jest NSString lub podklasa. Możesz więc zrobić jego kopię, więc jej wartość nie zmienia się za plecami. –

1

W innym przypadku użycia, jeśli (z jakiegokolwiek powodu) utworzyć własną podklasę NSString lub NSMutableString, stringWithString: zapewnia wygodny sposób na instancję z instancją obu NSString, NSMutableString lub MyCustomString.

0

Często używam +stringWithString:, kiedy potrzebuję stworzyć NSMutableString, ale zaczynam od wartości początkowej. Na przykład:

NSMutableString * output = [NSMutableString stringWithString:@"<ul>"]; 
for (NSString * item in anArray) { 
    [output appendFormat:@"<li>%@</li>", item]; 
} 
[output appendString:@"</ul>"]; 
0

FYI, że teraz jesteśmy kompilacji z włączonym ARC, nie trzeba ręcznie zwolnić w ogóle, ARC wstawi uwolnienie domaga podczas kompilacji. Więc jak jest jeszcze inaczej? stringWithString jest nadal dodawany do puli autorelease, która zostanie wyczerpana w przyszłości (chyba że utworzysz własną pulę autorelease). initWithString będzie mieć wywołanie zwalniające tuż przed zakończeniem funkcji, więc jeśli nie zatrzymałeś go gdzieś w metodzie, możesz być pewien, że ciąg znaków zostanie zniszczony przed końcem wywołania funkcji. Zapewnia to ściślejszą kontrolę nad zarządzaniem pamięcią, w przeciwieństwie do korzystania z autorejestrowanych obiektów.

Powiązane problemy