Управление памятью: строка NSStringWithCString: кодировка: - PullRequest
6 голосов
/ 26 октября 2011

Предположим, я получаю строку C из некоторой функции:

char * mystring = SomeCFunction(...);

И мне принадлежит эта строка (я отвечаю за ее освобождение, когда я закончу).

Если в Objective-C я создаю NSString *, используя:

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

Я все еще отвечаю за освобождение исходной строки C?

Я предполагаю, что ответ - да, но я не могу найти окончательный ответ в документации - и функциональность противоположного метода (cStringUsingEncoding), хотя и чувственная, действительно заставляет меня задуматься, потому что он обрабатывает cString освобождает вас.

Если ответ «да», то я также отвечаю за то, чтобы убедиться, что я не освобождаю строку c, прежде чем я закончу, используя NSString *, или функция скопирует для меня строку? Я спрашиваю это, потому что документация для stringWithCString говорит это:

Возвращает строку, содержащую байты в данном массиве C, интерпретированную в соответствии с заданной кодировкой.

Что все еще заставляет меня задуматься, скопировала ли она байты или просто указывает на них внутренне (а я в основном просто выполняю приведение).

Ответы [ 2 ]

8 голосов
/ 26 октября 2011

Копирует байты.

Если вы не хотите, чтобы были скопированы байты, вы можете использовать - (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)flag.

Если вы используете - (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding или какой-либо товарный метод, например stringWithCString:encoding:, который сам вызывает этот метод низкого уровня, байты копируются.

3 голосов
/ 26 октября 2011

API не знает, откуда берется указатель, который вы передаете, поэтому он не знает, как стать его владельцем.Это может быть из malloc (), но это также может быть внутренний указатель или из mmap (), в этом случае free () не будет работать.Таким образом, API вынужден копировать данные.

Единственный раз, когда вы можете передать владение буфером C API-интерфейсу Какао, - это если API позволяет вам сказать, что он нуждается в освобождении.Взгляните, например, на -[NSData initWithBytesNoCopy:length:freeWhenDone:].

...