NSString 到 C 风格的 char 数组在第二次调用 drawRect 时崩溃

Posted

技术标签:

【中文标题】NSString 到 C 风格的 char 数组在第二次调用 drawRect 时崩溃【英文标题】:NSString to C-style char array crashes on second invoke to drawRect 【发布时间】:2009-05-26 22:00:18 【问题描述】:

我正在尝试使用 Core Graphics 上下文编写文本。我第一次可以做到,没问题,但第二次我的 iPhone 应用程序崩溃了。这是一个代码sn-p:

NSString *name = [MyClass getName];
const char *cname = [name UTF8String];
[self drawText:context text:cname];

MyClassdrawText 是自定义类/方法,但你明白了。这三行住在drawRect:

第一次执行drawRect:,我看到了预期的文本。但是,在 any 刷新 drawRect: 时,行:

const char *cname = [name UTF8String];

导致我的应用程序崩溃并显示神秘的"GDB: Program loaded." 状态消息。

即使我使用getCString: 方法,我也会得到类似的响应。我想我可能缺少对 NSString 到 char 数组转换的基本理解。

【问题讨论】:

我对这篇文章太陌生了,所以我无法评价回复者。但是,它们是正确的,因为我取消了对已释放对象的引用。我将 NSString 设为全局变量(这很好,因为为每个 drawRect 重新分配它:无论如何似乎效率低下)。基本上我最终删除了第一行,一切都按预期工作。谢谢! 您应该能够接受其中一个答案作为正确答案,即使您无法调整它们。 【参考方案1】:

听起来您正在尝试调用已被释放的对象上的方法。 UTF8String 消息的问题是您无法保留返回的指针,因为在释放字符串时它可能会失效——如果您需要保留它,您必须复制字符串。但是,getCString:maxLength:encoding: 没有这个问题。

确保您遵循正确的内存管理协议。查看Memory Management Programming Guide for Cocoa,并仔细检查您是否在适当的时间向适当的对象发送retainreleaseautorelease 消息。有可能您不应该发送额外的 releaseautorelease,或者您忘记在某处发送 retain 字符串。

【讨论】:

【参考方案2】:

最可能的原因是您保留了对先前返回的 char* 的引用,而您在第二次调用时取消了对它的引用。根据规范,指针无效存储:The returned C string is automatically freed just as a returned object would be released; you should copy the C string if it needs to store it outside of the autorelease context in which the C string is created.

【讨论】:

以上是关于NSString 到 C 风格的 char 数组在第二次调用 drawRect 时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

C++ int main (int argc, char *argv[]) - argv 是 c 风格的数组吗?

c 风格的字符串安全吗?

将NSString转换为char数组[重复]

iOS char转NSString、NSString转char

iphone,如何打印char数组

Objective C - 以十六进制格式将 char[] 转换为 NSString