2011-10-25 8 views
6

Załóżmy Dostaję ciąg C z niektórych funkcji:Memory Management: NSString za stringWithCString: kodowanie:

char * mystring = SomeCFunction(...);

I mam ten ciąg (jestem odpowiedzialny za uwolnienie go kiedy skończę).

Jeżeli w Objective-C, tworzę NSString * używając:

NSString * mynsstring = [NSString stringWithCString:mystring 
              encoding:NSUTF8StringEncoding]; 

jestem nadal odpowiedzialny za uwolnienie oryginalnego C ciąg?

Zakładam, że odpowiedź brzmi "tak", ale nie mogę znaleźć ostatecznej odpowiedzi w dokumentacji - a funkcjonalność odwrotnej metody (cStringUsingEncoding), podczas gdy sensowna, daje mi pauzę, ponieważ obsługuje cString wyzwalający dla ciebie.

Jeśli odpowiedź brzmi "tak", to czy jestem również odpowiedzialny za upewnienie się, że nie zwolniłem ciągu znaków c przed zakończeniem korzystania z NSString *, czy funkcja kopiuje dla mnie ciąg? Pytam o to, ponieważ dokumentacja stringWithCString mówi:

Zwraca ciąg zawierający bajty w danej macierzy C, interpretować według danym kodowaniu.

Co nadal pozostawia mnie zastanawiającego się, czy faktycznie skopiował bajty, czy po prostu wskazuje na nie wewnętrznie (a ja po prostu robię obsadę).

Odpowiedz

8

Powoduje skopiowanie bajtów.

Jeśli nie chcesz, aby bajty były kopiowane, możesz zamiast tego użyć - (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)flag.

Jeśli użyjesz - (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding lub jakiejkolwiek metody towarowej, takiej jak stringWithCString:encoding:, która sama nazywa tę metodę niskiego poziomu, bajty są kopiowane.

+0

Ah! Jesteś niesamowity. Dziękuję Ci! Przyjmuję odpowiedź po upływie 6 minut, które pozostały w czasomierzu akceptującym blokowanie. – Steve

+0

To powinno być na docs –

+0

@ AndréFratelli Proponuję złożyć opinię (istnieje link na dole każdej strony dokumentacji online), więc Apple dodaje to tam ;-) – AliSoftware

3

Interfejs API nie ma pojęcia, skąd przechodzi wskaźnik, z którego pochodzi, więc nie wie, jak przejąć na własność. Może to być obiekt malloc(), ale może to być również wskaźnik wewnętrzny lub z mmap(), w którym to przypadku funkcja free() nie będzie działać. Więc interfejs API jest zmuszony do kopiowania danych.

Jedynym momentem, w którym można przenieść własność bufora C na interfejs API kakao, jest to, że interfejs API pozwala mu powiedzieć, że potrzebuje zwolnienia. Spójrz na przykład na -[NSData initWithBytesNoCopy:length:freeWhenDone:].

+0

+1, Tak, to sprawia, że ​​dużo sensu dla mnie ... czasami po prostu z dokumentami Apple były trochę bardziej wyraźne na temat takich rzeczy - zamiast zostawiać was, aby wydedukować te rzeczy dla siebie. W tym przypadku zmusiło mnie to do tak długiego wahania, że ​​pomyślałem, że powinienem zapytać. – Steve

+0

Wystarczająco fair. Zgłoś błąd i poproś o to, aby został wyraźnie zgłoszony w dokumentacji. – kperryua