IPhone - Objective C - 如何在多个线程中共享外部变量?

时间:2011-08-14 02:32:17

标签: iphone objective-c

在一个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

我是否应该能够从辅助线程中读取此变量?如果是这样,我做错了吗?

2 个答案:

答案 0 :(得分:5)

您的错误实际上是典型的内存分配错误。这样:

MY_GATEWAY = [NSMutableString stringWithString:MY_PROTOCOL];

创建一个自动释放的字符串,并将MY_GATEWAY设置为指向它。你实际上并不拥有这个字符串,所有你保证的是它至少会持续与调用堆栈一样长。因此,自动释放的对象通常用于从函数返回结果或创建临时对象,而无需明确担心所有权。

当你的第二个线程到达访问MY_GATEWAY时,原始字符串已经被释放,并且只是巧合,其他一些对象被放在同一个地址。

您想要做的是:

MY_GATEWAY = [[NSMutableString alloc] initWithString:MY_PROTOCOL];

在名称中使用new,alloc,retain或create进行的任何调用都会为您提供拥有引用。当您拥有自己的引用时,您肯定知道该对象将在您明确释放之前一直存在。

管理内存管理规则的官方指南是hereThis blog post也很有用。

如果您不担心内存管理问题,Apple已宣布适用于iOS 5的工具版本将能够为您解决大部分问题。详细信息属于NDA,但如果您使用开发人员计划帐户登录Apple开发人员网站,则可以获得下一版本工具和相关文档的测试版。请留意自动参考计数(或ARC)的参考。

答案 1 :(得分:1)

MY_GATEWAY = [[NSMutableString stringWithString:MY_PROTOCOL] retain];

否则你的MY_GATEWAY字符串会被自动释放。