在一个iPhone应用程序中,我创建了一个常量文件来保存我的全局变量:
MyConstants.h
extern NSMutableString * MY_GATEWAY;
MyConstants.m
NSMutableString * MY_GATEWAY;
在我的app委托中,我导入了MyConstants.h,并且可以成功附加到MY_GATEWAY并使用这样的URL初始化我的全局变量:
MY_GATEWAY = [NSMutableString stringWithString:MY_PROTOCOL];
[MY_GATEWAY appendString:MY_HOST];
在我的app委托中,在初始化MY_GATEWAY之后,我启动了一个新线程。我的线程类也导入MyConstants.h,在该线程的主循环中我尝试读取MY_GATEWAY,但值是垃圾:
2011-08-13 22:23:47.246 MyProject[930:5c03] da.lproj
我是否应该能够从辅助线程中读取此变量?如果是这样,我做错了吗?
答案 0 :(得分:5)
您的错误实际上是典型的内存分配错误。这样:
MY_GATEWAY = [NSMutableString stringWithString:MY_PROTOCOL];
创建一个自动释放的字符串,并将MY_GATEWAY设置为指向它。你实际上并不拥有这个字符串,所有你保证的是它至少会持续与调用堆栈一样长。因此,自动释放的对象通常用于从函数返回结果或创建临时对象,而无需明确担心所有权。
当你的第二个线程到达访问MY_GATEWAY时,原始字符串已经被释放,并且只是巧合,其他一些对象被放在同一个地址。
您想要做的是:
MY_GATEWAY = [[NSMutableString alloc] initWithString:MY_PROTOCOL];
在名称中使用new,alloc,retain或create进行的任何调用都会为您提供拥有引用。当您拥有自己的引用时,您肯定知道该对象将在您明确释放之前一直存在。
管理内存管理规则的官方指南是here。 This blog post也很有用。
如果您不担心内存管理问题,Apple已宣布适用于iOS 5的工具版本将能够为您解决大部分问题。详细信息属于NDA,但如果您使用开发人员计划帐户登录Apple开发人员网站,则可以获得下一版本工具和相关文档的测试版。请留意自动参考计数(或ARC)的参考。
答案 1 :(得分:1)
做
MY_GATEWAY = [[NSMutableString stringWithString:MY_PROTOCOL] retain];
否则你的MY_GATEWAY字符串会被自动释放。