假设,在 ARC 下,你可以声明一个这样的结构:
typedef struct {
__strong NSObject *someObject;
int someInteger;
} MyStruct;
然后你可能会写这样的代码:
MyStruct *thing = malloc(sizeof(MyStruct));
问题:malloc
不会将它返回的内存填零。一些随机值也是如此thing->someObject
- 不一定是NULL。然后像这样为它分配一个值:
thing->someObject = [[NSObject alloc] init];
在幕后,ARC 会将其转换为如下代码:
NSObject *temporary = [[NSObject alloc] init];
[thing->someObject release];
thing->someObject = temporary;
这里的问题是您的程序只是发送release
了一些随机值!此时您的应用程序可能会崩溃。
您可能会说 ARC 应该识别调用malloc
并注意设置someObject
为 NULL 以防止这种情况发生。问题是它malloc
可能包含在其他一些函数中,如下所示:
void *myAllocate(size_t size) {
void *p = malloc(size);
if (!p) {
// malloc failed. Try to free up some memory.
clearCaches();
p = malloc(size);
}
return p;
}
好的,现在 ARC 也必须知道你的myAllocate
函数......这可能在你作为二进制文件获得的某个静态库中。
您的应用程序甚至可能有自己的内存分配器,可以回收旧的分配,而无需每次都使用free
和。malloc
因此,即使malloc
在返回之前更改为零填充内存也行不通。ARC 必须知道程序中的任何自定义分配器。
使这项工作可靠地工作将非常非常困难。所以相反,ARC 的创造者只是放弃了,说“算了。我们不会让你在结构中放置__strong
和__weak
引用。”</p>
这就是为什么只有__unsafe_unretained
在告诉 ARC“不要尝试管理 this 引用的对象的所有权”时才能将对象指针放入结构体中。</p>
您可以尝试使用包含__unsafe_unretained
对象引用的结构,也许使用CFRetain
andCFRelease
手动保留和释放它们。然后您可以创建一个此类结构的数组。这很容易出错,因此只有在分析器告诉您它对性能至关重要时,您才应该这样做。
相反,只需创建一个新的 Objective-C 类而不是结构。@property
为您将放入结构中的每个字段分配一个类。使用 anNSMutableArray
来管理这个新类的实例数组。