内存管理:NSString的stringWithCString:编码:
假设我从某个函数获取一个 C 字符串:
char * mystring = SomeCFunction(...);
并且我拥有这个字符串(我负责在完成后释放它)。
如果在 Objective-C 中,我使用以下方法创建一个 NSString *
:
NSString * mynsstring = [NSString stringWithCString:mystring
encoding:NSUTF8StringEncoding];
我仍然负责释放原始 C 字符串吗?
我假设答案是肯定的,但我在文档中找不到明确的答案 - 而相反方法 (cStringUsingEncoding
) 的功能虽然很有意义,但确实让我犹豫了,因为它为您处理 cString 释放。
如果答案是肯定的,那么我是否还负责确保在使用 NSString *
之前不释放 c 字符串,或者该函数是否为我复制字符串?我问这个是因为 stringWithCString
的文档这么说:
返回包含给定 C 数组中字节的字符串(已解释) 根据给定的编码。
这仍然让我想知道它是否真的复制了字节,或者只是在内部指向它们(我基本上只是在进行强制转换)。
Suppose I'm getting a C string from some function:
char * mystring = SomeCFunction(...);
And I own this string (I'm responsible for freeing it when I'm done).
If, in Objective-C, I create an NSString *
using:
NSString * mynsstring = [NSString stringWithCString:mystring
encoding:NSUTF8StringEncoding];
Am I still responsible for freeing the original C string?
I'm assuming the answer is yes, but I can't find a definitive answer in the documentation - and the functionality of the opposite method (cStringUsingEncoding
), while sensical, does give me pause, because it handles the cString freeing for you.
If the answer is yes, then am I also responsible for making sure I don't free the c string before I'm done using the NSString *
, or does the function copy the string for me? I ask this because the documentation for stringWithCString
says it:
Returns a string containing the bytes in a given C array, interpreted
according to a given encoding.
Which still leaves me wondering if it actually copied the bytes, or is just pointing at them internally (and I'm basically just doing a cast).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它确实复制字节。
如果您不想复制字节,可以使用
- (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:
它本身调用这个低级方法,字节被复制。It does copy the bytes.
If you don't want the bytes to be copied, you may use
- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)flag
instead.If you use
- (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding
, or any commodity method likestringWithCString:encoding:
that itself calls this low-level method, the bytes are copied.API 不知道您传递给它的指针来自哪里,因此它不知道如何获取它的所有权。它可能来自 malloc(),但也可能是内部指针或来自 mmap(),在这种情况下 free() 将不起作用。所以API被迫复制数据。
唯一可以将 C 缓冲区的所有权传递给 Cocoa API 的情况是 API 允许您告诉它需要释放。例如,看看
-[NSData initWithBytesNoCopy:length:freeWhenDone:]
。The API has no idea where the pointer you pass it comes from so it doesn't know how to take ownership of it. It could be from malloc(), but it could also be an interior pointer or from mmap(), in which case free() won't work. So the API is forced to copy the data.
The only time you can pass ownership of a C buffer to a Cocoa API is if the API allows you to tell it it needs freeing. Take a look at
-[NSData initWithBytesNoCopy:length:freeWhenDone:]
, for example.