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

Joh*_*ock 1 iphone objective-c

在一个iPhone应用程序中,我创建了一个常量文件来保存我的全局变量:

MyConstants.h
extern NSMutableString * MY_GATEWAY;


MyConstants.m
NSMutableString * MY_GATEWAY;
Run Code Online (Sandbox Code Playgroud)

在我的app委托中,我导入了MyConstants.h,并且可以成功附加到MY_GATEWAY并使用以下URL来初始化我的全局变量:

 MY_GATEWAY = [NSMutableString stringWithString:MY_PROTOCOL];
[MY_GATEWAY appendString:MY_HOST];
Run Code Online (Sandbox Code Playgroud)

从我的app delegate,在初始化MY_GATEWAY后,我启动了一个新线程.我的线程类也导入MyConstants.h,在该线程的主循环中我尝试读取MY_GATEWAY,但值为garbage:

2011-08-13 22:23:47.246 MyProject[930:5c03] da.lproj
Run Code Online (Sandbox Code Playgroud)

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

Tom*_*mmy 5

你的错误实际上是一个典型的内存分配错误.这个:

MY_GATEWAY = [NSMutableString stringWithString:MY_PROTOCOL];
Run Code Online (Sandbox Code Playgroud)

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

当你的第二个线程到达访问MY_GATEWAY时,原始字符串已被解除分配,并且巧合地将一些其他对象放在同一地址.

你想要做的是:

MY_GATEWAY = [[NSMutableString alloc] initWithString:MY_PROTOCOL];
Run Code Online (Sandbox Code Playgroud)

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

这里有关于内存管理规则的官方指南.这篇博文也很有用.

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